package com.xbongbong.saas.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.admin.domain.entity.AppInstallEntity;
import com.xbongbong.admin.domain.entity.MarketDetailEntity;
import com.xbongbong.admin.domain.entity.PaasLabelEntity;
import com.xbongbong.admin.model.AppInstallModel;
import com.xbongbong.admin.model.PaasLabelModel;
import com.xbongbong.admin.pojo.dto.MirrorInstructionAllDTO;
import com.xbongbong.admin.pojo.dto.MirrorInstructionDTO;
import com.xbongbong.admin.pojo.vo.MirrorInstructionAllVO;
import com.xbongbong.admin.pojo.vo.MirrorInstructionVO;
import com.xbongbong.callback.service.ApiCallBackService;
import com.xbongbong.crm.service.SearchCustomerService;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.constant.TimeConstant;
import com.xbongbong.paas.domain.entity.PaasAppEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.PaasMenuEntity;
import com.xbongbong.paas.domain.entity.StageProcessEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.elasticsearch.pojo.XbbAggregatedPage;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.help.EsignHelp;
import com.xbongbong.sys.help.PackageHelp;
import com.xbongbong.paas.help.SerialNoHelp;
import com.xbongbong.paas.help.menu.InitDistributorMenuHelp;
import com.xbongbong.paas.help.menu.InitMenuHelp;
import com.xbongbong.paas.help.menu.InitPriceMenuHelp;
import com.xbongbong.paas.manager.feign.MirrorFeignClent;
import com.xbongbong.paas.model.FineClueCompanyModel;
import com.xbongbong.paas.model.PaasAppModel;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.model.PaasMenuModel;
import com.xbongbong.paas.model.SearchCustomerCompanyModel;
import com.xbongbong.paas.model.SearchCustomerUserModel;
import com.xbongbong.paas.model.StageProcessModel;
import com.xbongbong.paas.pojo.SmsSpacePojo;
import com.xbongbong.paas.pojo.dto.EnableApplicationListDTO;
import com.xbongbong.paas.pojo.dto.SerialNoDTO;
import com.xbongbong.paas.pojo.vo.EnableApplicationListVO;
import com.xbongbong.paas.pojo.vo.SerialNoVO;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisConstant;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.redis.RedisTimeConstant;
import com.xbongbong.paas.service.PaasAppService;
import com.xbongbong.paas.service.PaasFormDataService;
import com.xbongbong.paas.service.PaasMenuService;
import com.xbongbong.paas.service.SMSSpaceService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.PaasDateUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.BaseDTO;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.toolbox.wrap.XbbResponse;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.appmodule.pojo.AppModulePojo;
import com.xbongbong.pro.appmodule.pojo.AppModuleTabPojo;
import com.xbongbong.pro.appmodule.pojo.AppRemindPojo;
import com.xbongbong.pro.appmodule.pojo.dto.AppModuleDetailDTO;
import com.xbongbong.pro.appmodule.pojo.dto.AppModuleListDTO;
import com.xbongbong.pro.appmodule.pojo.dto.AppModuleOpenDTO;
import com.xbongbong.pro.appmodule.pojo.dto.AppModuleSaveDTO;
import com.xbongbong.pro.appmodule.pojo.dto.SendSMSDTO;
import com.xbongbong.pro.appmodule.pojo.vo.AppModuleDetailVO;
import com.xbongbong.pro.appmodule.pojo.vo.AppModuleDisenableListVO;
import com.xbongbong.pro.appmodule.pojo.vo.AppModuleHotVO;
import com.xbongbong.pro.appmodule.pojo.vo.AppModuleListVO;
import com.xbongbong.pro.appmodule.pojo.vo.AppModuleOpenVO;
import com.xbongbong.pro.appmodule.pojo.vo.AppModuleSaveVO;
import com.xbongbong.pro.appmodule.pojo.vo.AppRemindVO;
import com.xbongbong.pro.common.pojo.dto.CustomerCheckRepeatDTO;
import com.xbongbong.pro.config.ProBaseConfig;
import com.xbongbong.pro.constant.DingTalkPayConstant;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.detailtab.dto.UpdateMyTeamDTO;
import com.xbongbong.pro.domain.entity.AppModuleEntity;
import com.xbongbong.pro.domain.entity.FineClueCompanyEntity;
import com.xbongbong.pro.domain.entity.SearchCustomerCompanyEntity;
import com.xbongbong.pro.domain.entity.SearchCustomerUserEntity;
import com.xbongbong.pro.enums.AppOperateProcessEnum;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.FineClueEnum;
import com.xbongbong.pro.enums.ModuleAppOperateEnum;
import com.xbongbong.pro.enums.ModuleAppTypeEnum;
import com.xbongbong.pro.enums.ModuleCenterTabEnum;
import com.xbongbong.pro.enums.PackageTypeEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.SoukeMealEnum;
import com.xbongbong.pro.enums.SoukeNumTypeEnum;
import com.xbongbong.pro.enums.ValueAddedTypeEnum;
import com.xbongbong.pro.enums.errorcodes.CoolAppErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SearchCustomerErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.TemplateCenterErrorCodeEnum;
import com.xbongbong.pro.enums.menu.enums.SystemAppMenuEnum;
import com.xbongbong.pro.enums.permission.enums.ProPermissionAliasEnum;
import com.xbongbong.pro.esign.pojo.dto.EsignAuthUrlDTO;
import com.xbongbong.pro.esign.pojo.vo.EsignAuthUrlVO;
import com.xbongbong.pro.esign.pojo.vo.EsignCorpStatusVO;
import com.xbongbong.pro.formdata.pojo.dto.DefaultOwnerAndCoUserGetDTO;
import com.xbongbong.pro.formdata.pojo.vo.DefaultOwnerAndCoUserGetVO;
import com.xbongbong.pro.menu.pojo.dto.MenuChangeStateDTO;
import com.xbongbong.pro.menu.pojo.dto.MenuInitDTO;
import com.xbongbong.pro.menu.pojo.vo.MenuInitVO;
import com.xbongbong.pro.message.constant.OpportunityPushConstant;
import com.xbongbong.pro.message.enums.PushTypeEnum;
import com.xbongbong.pro.message.pojo.PushRefTypePojo;
import com.xbongbong.pro.message.pojo.dto.MessageRabbitMqDTO;
import com.xbongbong.pro.rabbitmq.producer.BaseProducer;
import com.xbongbong.pro.searchcustomer.pojo.dto.Extra;
import com.xbongbong.pro.searchcustomer.pojo.dto.SearchCustomerDTO;
import com.xbongbong.pro.searchcustomer.pojo.dto.SearchCustomerMealDTO;
import com.xbongbong.pro.user.pojo.ReturnUserAndDepartmentPojo;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.constant.UserConstant;
import com.xbongbong.saas.domain.entity.EsignTaskEntity;
import com.xbongbong.saas.domain.entity.OpportunityStageLogEntity;
import com.xbongbong.saas.domain.entity.OpportunityUserEntity;
import com.xbongbong.saas.domain.entity.SaleStageEntity;
import com.xbongbong.saas.domain.entity.UserTeamEntity;
import com.xbongbong.saas.domain.entity.ext.OpportunityEntityExt;
import com.xbongbong.saas.enums.CheckRepeatRuleEnum;
import com.xbongbong.saas.enums.CompanyConfigEnum;
import com.xbongbong.saas.enums.EsignTaskTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.SalesOpportunityEnum;
import com.xbongbong.saas.help.AppModuleHelp;
import com.xbongbong.saas.model.AppModuleModel;
import com.xbongbong.saas.model.EsignTaskModel;
import com.xbongbong.saas.model.MarketDetailModel;
import com.xbongbong.saas.model.OpportunityModel;
import com.xbongbong.saas.model.OpportunityStageLogModel;
import com.xbongbong.saas.model.OpportunityUserModel;
import com.xbongbong.saas.model.SaleStageModel;
import com.xbongbong.saas.model.StageWorkModel;
import com.xbongbong.saas.service.AppModuleService;
import com.xbongbong.saas.service.CustomerService;
import com.xbongbong.saas.service.SaasDetailTabService;
import com.xbongbong.saas.service.toolbox.help.UserTeamHelp;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.domain.entity.CompanyConfigEntity;
import com.xbongbong.sys.domain.entity.CompanyEntity;
import com.xbongbong.sys.domain.entity.FeeEntity;
import com.xbongbong.sys.domain.entity.FeeLogEntity;
import com.xbongbong.sys.domain.entity.UserConfigEntity;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.domain.entity.ext.FeeEntityExt;
import com.xbongbong.sys.domain.entity.ext.FeeLogEntityExt;
import com.xbongbong.sys.enums.UserConfigEnum;
import com.xbongbong.sys.model.CompanyConfigModel;
import com.xbongbong.sys.model.CompanyModel;
import com.xbongbong.sys.model.FeeLogModel;
import com.xbongbong.sys.model.FeeModel;
import com.xbongbong.sys.model.PriceSetModel;
import com.xbongbong.sys.model.UserConfigModel;
import com.xbongbong.sys.model.UserModel;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @description: 模板中心
 * @Author: hongxiao
 * @date: 2019-03-02 16:52
 * @since v1.0
 */
@Service("appModuleService")
public class AppModuleServiceImpl implements AppModuleService {

    @Resource
    private AppModuleModel appModuleModel;
    @Resource
    private PaasAppService paasAppService;
    @Resource
    private InitMenuHelp initMenuHelp;
    @Resource
    private PaasAppModel paasAppModel;
    @Resource
    private SearchCustomerService searchCustomerService;
    @Resource
    private SearchCustomerCompanyModel searchCustomerCompanyModel;
    @Resource
    private SearchCustomerUserModel searchCustomerUserModel;
    @Resource
    private FeeModel feeModel;
    @Resource
    private CompanyModel companyModel;
    @Resource
    private PaasRedisHelper paasRedisHelper;
    @Resource
    private AppModuleHelp appModuleHelp;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private CustomerService customerService;
    @Resource
    private PaasFormDataService paasFormDataService;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private PaasLabelModel paasLabelModel;
    @Resource
    private AppInstallModel appInstallModel;
    @Resource
    private MarketDetailModel marketDetailModel;
    @Resource
    private UserConfigModel userConfigModel;
    @Resource
    private UserModel userModel;
    @Resource
    private MirrorFeignClent mirrorFeignClent;
    @Resource
    private FeeLogModel feeLogModel;
    @Resource
    private OpportunityModel opportunityModel;
    @Resource
    private EsignHelp esignHelp;
    @Resource
    private EsignTaskModel esignTaskModel;
    @Resource
    private BaseProducer baseProducer;
    @Resource
    private SaasDetailTabService saasDetailTabService;
    @Resource
    private PackageHelp packageHelp;
    @Resource
    private PaasMenuService paasMenuService;
    @Resource
    private SerialNoHelp serialNoHelp;
    @Resource
    private CompanyConfigModel companyConfigModel;
    @Resource
    private InitDistributorMenuHelp initDistributorMenuHelp;
    @Resource
    private InitPriceMenuHelp initPriceMenuHelp;
    @Resource
    private PaasMenuModel paasMenuModel;
    @Resource
    private PriceSetModel priceSetModel;
    @Resource
    private StageProcessModel stageProcessModel;
    @Resource
    private SaleStageModel saleStageModel;
    @Resource
    private OpportunityStageLogModel opportunityStageLogModel;
    @Resource
    private StageWorkModel stageWorkModel;
    @Resource
    private FineClueCompanyModel fineClueCompanyModel;
    @Resource
    private ApiCallBackService apiCallBackService;
    @Resource
    private UserTeamHelp userTeamHelp;
    @Resource
    private OpportunityUserModel opportunityUserModel;

    private static final Logger LOG = LoggerFactory.getLogger(AppModuleServiceImpl.class);

    @Override
    public AppModuleListVO list(AppModuleListDTO listDTO) throws XbbException {
        AppModuleListVO listVO = new AppModuleListVO();
        String corpid = listDTO.getCorpid();
        // 全新上架(模板)
        List<AppModulePojo> newShelvesList = new ArrayList<>();
        // 官方应用
        List<AppModulePojo> officialList = new ArrayList<>();
        // 增值应用
        List<AppModulePojo> incrementList = new ArrayList<>();
        // 第三方应用
        List<AppModulePojo> thirdPartyList = new ArrayList<>();
        // 增值服务
        List<AppModulePojo> incrementServiceList = new ArrayList<>();

        // 获取已开通的应用模板
        Map<String, PaasAppEntity> appEntityMap = getOpenApp(corpid, listDTO.getUserId());
        // 获取公司级配置
        List<String> aliasList = Arrays.asList(CompanyConfigEnum.PRICE_MANAGE.getAlias(), CompanyConfigEnum.LOGISTICS_TRACKING.getAlias(), CompanyConfigEnum.ELECTRONIC_FACE_SHEET.getAlias());
        Map<String,String> companyConfigMap = companyConfigModel.getConfigValueMap(corpid,aliasList);
        // 获取列表
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("nameLike", listDTO.getNameLike());
        param.put("shelves",  1);
        param.put("del", DelEnum.NORMAL.getDel());
        List<AppModuleEntity> list = appModuleModel.getList(param);
        Boolean isStandardWithFeeType = packageHelp.isStandardWithFeeType(corpid);
        boolean hasApplyTrial = feeLogModel.getByType(corpid, ValueAddedTypeEnum.DISTRIBUTOR.getType()).isEmpty();
        // 筛选app_type不是模板(镜像应用)
        list.stream().filter(item -> !Objects.equals(item.getAppType(), 3)).collect(Collectors.toList()).forEach(item -> {

            if (Objects.equals(item.getAlias(), SystemAppMenuEnum.EXPENSE_MANAGEMENT.getAlias())) {
                //移动端不显示每刻报销
//                if (Objects.equals(listDTO.getPlatform(), PlatFormEnum.DINGTALK.getValue())) {
//                    return;
//                }
//                item.setName("每刻报销");

                //隐藏掉
                return;
            }
            if (Objects.equals(item.getAlias(), ValueAddedTypeEnum.DISTRIBUTOR.getAlias()) && !hasApplyTrial) {
                item.setOperateType(AppOperateProcessEnum.APPLY_OPEN_INDEX.getOperateType());
            }
            Integer type = Integer.valueOf(item.getType());
            AppModulePojo appModulePojo = new AppModulePojo();
            BeanUtil.copyProperties(item, appModulePojo);
            appModulePojo.setAppModuleId(item.getId());
            // 展示“new”标签的处理
            String newLabelRedisKey = item.getId() + corpid + listDTO.getUserId();
            appModulePojo.setIsNew(appModuleHelp.showNewLabel(item, newLabelRedisKey));
            if (companyConfigMap.containsKey(item.getAlias())) {
                String alias = item.getAlias();
                getOperateStatusByConfig(companyConfigMap.get(alias), appModulePojo);
            } else {
                PaasAppEntity paasAppEntity = appEntityMap.get(item.getAlias());
                dealSpecialMarket(corpid, item, paasAppEntity, isStandardWithFeeType, listDTO);
                getOperateStatus(paasAppEntity, item, appModulePojo, corpid, listDTO.getPlatform());
            }
            if (Objects.equals(type, ModuleAppTypeEnum.OFFICIAL_APPLICATION.getType())) {
                officialList.add(appModulePojo);
            } else if (Objects.equals(type, ModuleAppTypeEnum.INCREMENT_APPLICATION.getType())) {
                incrementList.add(appModulePojo);
            } else if (Objects.equals(type, ModuleAppTypeEnum.THIRD_PARTY_APPLICATION.getType())) {
                thirdPartyList.add(appModulePojo);
            } else if (Objects.equals(type, ModuleAppTypeEnum.INCREMENT_SERVICE.getType())) {
                incrementServiceList.add(appModulePojo);
            }
        });
        // 获取镜像应用
        List<AppModuleEntity> mirrorList = list.stream().filter(item -> Objects.equals(item.getAppType(), 3)).collect(Collectors.toList());
        // 营销页应用与镜像应用
        Map<String, AppModuleTabPojo> templateMap = new HashMap<>();
        Map<Long, PaasLabelEntity> labelEntityMap = new HashMap<>();
        List<ModuleCenterTabEnum> tabEnums = new ArrayList<>(Arrays.asList(ModuleCenterTabEnum.values()))
                .stream().filter(item -> !Objects.equals(item, ModuleCenterTabEnum.UNKONW)).collect(Collectors.toList());
        tabEnums.forEach(item ->{
            AppModuleTabPojo pojo = new AppModuleTabPojo();
            BeanUtil.copyProperties(item, pojo);
            int type = pojo.getType();
            if (Objects.equals(type, ModuleCenterTabEnum.SELECTED_RECOMMEND.getType())) {
                // TODO 添加精选推荐的应用
                List<MarketDetailEntity> marketList = marketDetailModel.publishMarket();
                marketList.stream().sorted(Comparator.comparing(MarketDetailEntity::getSort).reversed()).forEach(market -> {
                    AppModulePojo modulePojo = new AppModulePojo();
                    BeanUtil.copyProperties(market, modulePojo);
                    modulePojo.setAppModuleId(market.getId());
                    if (StringUtil.isNotEmpty(market.getImage())) {
                        List<String> images = JSONArray.parseArray(market.getImage(), String.class);
                        modulePojo.setImage(images);
                    }
                    pojo.getAppList().add(modulePojo);
                });
            } else {
                // 已开启的标签
                List<PaasLabelEntity> labelList = paasLabelModel.getByType(type);
                if (CollectionsUtil.isEmpty(labelList)) {
                    return;
                }
                labelList.forEach(entity -> {
                    AppModuleTabPojo tabPojo = new AppModuleTabPojo();
                    BeanUtil.copyProperties(entity, tabPojo);
                    tabPojo.setType(entity.getId().intValue());
                    pojo.getChildMap().put(String.valueOf(tabPojo.getType()), tabPojo);
                    labelEntityMap.put(entity.getId(), entity);
                });
            }
            templateMap.put(String.valueOf(type), pojo);
        });

        mirrorList.stream().filter(item -> Objects.equals(item.getNewApp(), 1)).sorted(Comparator.comparing(AppModuleEntity::getAddTime).reversed()).forEach(appModuleEntity -> {
            AppModulePojo appModulePojo = new AppModulePojo();
            BeanUtil.copyProperties(appModuleEntity, appModulePojo);
            appModulePojo.setAppModuleId(appModuleEntity.getId());
            if(appModuleEntity.getMirrorId() != null){
                appModulePojo.setMirrorIdIn(JSONObject.parseArray(appModuleEntity.getMirrorId().toJSONString(), Long.class));
            }
            // 展示“new”标签的处理
            String newLabelRedisKey = appModuleEntity.getId() + listDTO.getCorpid() + listDTO.getUserId();
            appModulePojo.setIsNew(appModuleHelp.showNewLabel(appModuleEntity, newLabelRedisKey));
            getOperateStatus(null, appModuleEntity, appModulePojo, corpid, listDTO.getPlatform());
            newShelvesList.add(appModulePojo);
        });

        mirrorList.stream().filter(item -> Objects.equals(item.getNewApp(), 1)).sorted(Comparator.comparing(AppModuleEntity::getAddTime).reversed()).forEach(appModuleEntity -> {
            AppModulePojo appModulePojo = new AppModulePojo();
            BeanUtil.copyProperties(appModuleEntity, appModulePojo);
            appModulePojo.setAppModuleId(appModuleEntity.getId());
            // 展示“new”标签的处理
            String newLabelRedisKey = appModuleEntity.getId() + listDTO.getCorpid() + listDTO.getUserId();
            appModulePojo.setIsNew(appModuleHelp.showNewLabel(appModuleEntity, newLabelRedisKey));
            getOperateStatus(null, appModuleEntity, appModulePojo, corpid, listDTO.getPlatform());
            List<String> typeList = StringUtil.toStringList(appModuleEntity.getType(), "|");
            if (typeList != null) {
                typeList.forEach(entity -> {
                    if (!labelEntityMap.keySet().contains(Long.valueOf(entity))) {
                        return;
                    }
                    int type = labelEntityMap.get(Long.valueOf(entity)).getType();
                    AppModuleTabPojo appModuleTabPojo = templateMap.get(String.valueOf(type));
                    if (appModuleTabPojo.getChildMap().keySet().contains(entity)) {
                        appModuleTabPojo.getChildMap().get(entity).getAppList().add(appModulePojo);
                        appModuleTabPojo.getLabelAppList().add(appModulePojo);
                    }
                });
            }
        });

        // 行业全部
        if(templateMap.containsKey(String.valueOf(ModuleCenterTabEnum.INDUSTRY.getType()))){
            AppModuleTabPojo pojo = templateMap.get(String.valueOf(ModuleCenterTabEnum.INDUSTRY.getType()));
            Map<String,AppModuleTabPojo> childMap = pojo.getChildMap();
            List<AppModulePojo> allAppList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Iterator<Map.Entry<String,AppModuleTabPojo>> entries = childMap.entrySet().iterator();
            while (entries.hasNext()) {
                Map.Entry<String,AppModuleTabPojo> entry = entries.next();
                AppModuleTabPojo tabPojo = entry.getValue();
                allAppList.addAll(tabPojo.getAppList());
            }
            AppModuleTabPojo allTab = new AppModuleTabPojo();
            allTab.setAppList(allAppList);
            allTab.setChildMap(new HashMap<>());
            allTab.setLabelAppList(new ArrayList<>());
            allTab.setName(I18nMessageUtil.getMessage(StringConstant.ALL));
            allTab.setSort(BasicConstant.ZERO);
            allTab.setType(BasicConstant.ZERO);
            childMap.put("0", allTab);
        }

        // 用途全部
        if(templateMap.containsKey(String.valueOf(ModuleCenterTabEnum.PURPOSE.getType()))){
            AppModuleTabPojo pojo = templateMap.get(String.valueOf(ModuleCenterTabEnum.PURPOSE.getType()));
            Map<String,AppModuleTabPojo> childMap = pojo.getChildMap();
            List<AppModulePojo> allAppList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Iterator<Map.Entry<String,AppModuleTabPojo>> entries = childMap.entrySet().iterator();
            while (entries.hasNext()) {
                Map.Entry<String,AppModuleTabPojo> entry = entries.next();
                AppModuleTabPojo tabPojo = entry.getValue();
                allAppList.addAll(tabPojo.getAppList());
            }
            AppModuleTabPojo allTab = new AppModuleTabPojo();
            allTab.setAppList(allAppList);
            allTab.setChildMap(new HashMap<>());
            allTab.setLabelAppList(new ArrayList<>());
            allTab.setName(I18nMessageUtil.getMessage(StringConstant.ALL));
            allTab.setSort(BasicConstant.ZERO);
            allTab.setType(BasicConstant.ZERO);
            childMap.put("0", allTab);
        }

        // banner营销页应用
        List<AppModulePojo> bannerList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);

        List<MarketDetailEntity> marketList = marketDetailModel.bannerByPublish();
        List<Long> appIdIn = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        marketList.forEach(item -> appIdIn.add(item.getAppId()));
        // 上架的应用
        Map<String, Object> appParam = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        appParam.put("idIn", appIdIn);
        appParam.put("shelves", 1);
        List<AppModuleEntity> appList = appModuleModel.getList(appParam);
        Map<Long, AppModuleEntity> shelvesMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        appList.forEach(item -> shelvesMap.put(item.getId(), item));

        /*for(MarketDetailEntity marketEntity : marketList){
            Long appModuleId = marketEntity.getAppId();
            List<String> datailImages = JSONArray.parseArray(marketEntity.getImage(), String.class);
            if(shelvesMap.containsKey(appModuleId)){
                AppModulePojo appModulePojo = new AppModulePojo();
                AppModuleEntity appModuleEntity = shelvesMap.get(appModuleId);
                BeanUtil.copyProperties(appModuleEntity, appModulePojo);

                appModulePojo.setImage(datailImages);
                appModulePojo.setContent(marketEntity.getContent());
                bannerList.add(appModulePojo);
            }
        }*/


        Map<Long, List<String>> appModuleAndImageMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, String> appModuleAndUrlMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, String> appModuleAndContentMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, Long> appModuleAndDetailIdMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, Integer> detailIdAndSortMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for(MarketDetailEntity detailEntity : marketList){
            Long appId = detailEntity.getAppId();
            List<String> datailImages = JSONArray.parseArray(detailEntity.getImage(), String.class);
            if(appModuleAndImageMap.containsKey(appId)){
                List<String> images = appModuleAndImageMap.get(appId) == null ? new ArrayList<>() : appModuleAndImageMap.get(appId);
                images.addAll(datailImages);
            }
            appModuleAndImageMap.put(appId, datailImages);
            String bannerUrl = detailEntity.getBannerUrl();
            appModuleAndUrlMap.put(appId, bannerUrl);
            String bannerContent = detailEntity.getContent();
            appModuleAndContentMap.put(appId, bannerContent);

            appModuleAndDetailIdMap.put(appId, detailEntity.getId());
            detailIdAndSortMap.put(detailEntity.getId(), detailEntity.getSort());
        }
        // 应用详情页banner
        appList.stream().filter(item -> Objects.equals(item.getShelves(), 1)).sorted(Comparator.comparing(AppModuleEntity::getAddTime).reversed()).forEach(appModuleEntity -> {
            if(appModuleAndImageMap.containsKey(appModuleEntity.getId())){
                AppModulePojo appModulePojo = new AppModulePojo();
                BeanUtil.copyProperties(appModuleEntity, appModulePojo);
                appModulePojo.setAppModuleId(appModuleEntity.getId());
                if(appModuleEntity.getMirrorId() != null){
                    appModulePojo.setMirrorIdIn(JSONObject.parseArray(appModuleEntity.getMirrorId().toJSONString(), Long.class));
                }
                getOperateStatus(null, appModuleEntity, appModulePojo, corpid, listDTO.getPlatform());
                // 轮播图
                List<String> images = appModuleAndImageMap.get(appModuleEntity.getId()) == null ? new ArrayList<>() : appModuleAndImageMap.get(appModuleEntity.getId());
                appModulePojo.setImage(images);
                // 链接
                String bannerUrl = appModuleAndUrlMap.get(appModuleEntity.getId()) == null ? "" : appModuleAndUrlMap.get(appModuleEntity.getId());
                appModulePojo.setBannerUrl(bannerUrl);
                // content
                String bannerContent = appModuleAndContentMap.get(appModuleEntity.getId()) == null ? "" : appModuleAndContentMap.get(appModuleEntity.getId());
                appModulePojo.setBannerContent(bannerContent);

                Long datailId = appModuleAndDetailIdMap.get(appModuleEntity.getId()) == null ? 0L : appModuleAndDetailIdMap.get(appModuleEntity.getId());
                Integer sort = detailIdAndSortMap.get(datailId) == null ? BasicConstant.ZERO : detailIdAndSortMap.get(datailId);
                appModulePojo.setSort(sort);
                bannerList.add(appModulePojo);
            }
        });
        // 跳转链接或者跳转页面banner
        marketList.stream().filter(item -> Objects.equals(item.getAppId(), -1L)).sorted(Comparator.comparing(MarketDetailEntity::getAddTime).reversed()).forEach(marketDetailEntity -> {
            AppModulePojo appModulePojo = new AppModulePojo();
            BeanUtil.copyProperties(marketDetailEntity, appModulePojo);
            appModulePojo.setAppModuleId(null);
            // 轮播图
            List<String> datailImages = JSONArray.parseArray(marketDetailEntity.getImage(), String.class);
            appModulePojo.setImage(datailImages);
            // 链接
            String bannerUrl = marketDetailEntity.getBannerUrl();
            if(bannerUrl != null){}
            appModulePojo.setBannerUrl(bannerUrl);
            // content
            String content = marketDetailEntity.getContent();
            if(content != null){
                appModulePojo.setBannerContent(content);
            }
            appModulePojo.setSort(marketDetailEntity.getSort());
            bannerList.add(appModulePojo);
        });

        if (!bannerList.isEmpty()) {
            Collections.sort(bannerList, new Comparator<AppModulePojo>() {
                @Override
                public int compare(AppModulePojo o1, AppModulePojo o2) {
                    //降序
                    return o2.getSort() - o1.getSort();
                }
            });
        }


        listVO.setNewShelvesList(newShelvesList);
        listVO.setOfficialList(officialList);
        listVO.setIncrementList(incrementList);
        listVO.setThirdPartyList(thirdPartyList);
        listVO.setIncrementServiceList(incrementServiceList);
        listVO.setTemplateMap(templateMap);
        listVO.setBannerList(bannerList);
        return listVO;
    }

    public void dealSpecialMarket(String corpid, AppModuleEntity item, PaasAppEntity paasAppEntity, Boolean standardWithFeeType,AppModuleListDTO listDTO) {
        try {
            if (Objects.equals(item.getAlias(), XbbRefTypeEnum.MARKET_MANAGEMENT.getAlias())) {
                // 对市场活动进行特殊处理 标准版为申请开通,旗舰版和高级版为开启关闭
                // 判断套餐
                if (!standardWithFeeType) {
                    item.setOperateType(AppOperateProcessEnum.START_INDEX.getOperateType());
                }
                if (standardWithFeeType && Objects.nonNull(paasAppEntity) && !Objects.equals(paasAppEntity.getEnable(), 0)) {
                    MenuChangeStateDTO menuChangeStateDTO  = new MenuChangeStateDTO();
                    BeanUtil.copyProperties(listDTO, menuChangeStateDTO);
                    menuChangeStateDTO.setAppId(paasAppEntity.getId());
                    menuChangeStateDTO.setEnable(false);
                    menuChangeStateDTO.setTarget(BasicConstant.ONE);
                    paasMenuService.changeState(menuChangeStateDTO);
                    //应用是市场管理的话，刷新缓存
                    paasAppService.setEnable2RedisByAlias(corpid, SystemAppMenuEnum.MARKET_MANAGEMENT.getAlias(), paasAppEntity.getEnable());
                    paasAppEntity.setEnable(0);
                }
            }
        } catch (XbbException e) {
        }
    }

    @Override
    public AppModuleListVO search(@Valid AppModuleListDTO listDTO) throws XbbException {
        AppModuleListVO listVO = new AppModuleListVO();
        String corpid = listDTO.getCorpid();
        // 获取已开通的应用模板
        Map<String, PaasAppEntity> appEntityMap = getOpenApp(corpid, listDTO.getUserId());
        // 获取列表
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("nameLike", listDTO.getNameLike());
        param.put("shelves", 1);
        param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        List<AppModuleEntity> list = appModuleModel.getList(param);
        List<AppModulePojo> allList = new ArrayList<>();
        list.forEach(item -> {
            AppModulePojo pojo = new AppModulePojo();
            BeanUtil.copyProperties(item, pojo);
            pojo.setAppModuleId(item.getId());
            // 展示“new”标签的处理
            String newLabelRedisKey = item.getId() + corpid + listDTO.getUserId();
            pojo.setIsNew(appModuleHelp.showNewLabel(item, newLabelRedisKey));
            PaasAppEntity paasAppEntity = appEntityMap.get(item.getAlias());
            getOperateStatus(paasAppEntity, item, pojo, corpid, listDTO.getPlatform());

            allList.add(pojo);
        });
        listVO.setAllList(allList);
        return listVO;
    }

    @Override
    public AppModuleDetailVO detail(AppModuleDetailDTO detailDTO) throws XbbException {
        AppModuleDetailVO detailVO = new AppModuleDetailVO();
        String corpid = detailDTO.getCorpid();
        Boolean isMarket = detailDTO.getIsMarket();
        Long appModuleId = detailDTO.getAppModuleId();
        if (Objects.nonNull(isMarket) && isMarket) {
            MarketDetailEntity marketEntity = marketDetailModel.getByKey(appModuleId);
            detailVO.setContent(marketEntity.getContent());
            appModuleId = marketEntity.getAppId();
        }

        AppModuleEntity entity = appModuleModel.getByKey(appModuleId);
        if (entity == null) {
            throw new XbbException(TemplateCenterErrorCodeEnum.API_ERROR_402003, TemplateCenterErrorCodeEnum.API_ERROR_402003.getMsg());
        }
        if (Objects.equals(entity.getShelves(), 0)) {
            throw new XbbException(TemplateCenterErrorCodeEnum.API_ERROR_402006, TemplateCenterErrorCodeEnum.API_ERROR_402006.getMsg());
        }
        if (entity.getNewApp() == 1 && DateUtil.getInt() - entity.getAddTime() < RedisConstant.HUGE_DURATION) {
            String key = entity.getId() + corpid + detailDTO .getUserId();
            String value = paasRedisHelper.getValue(RedisPrefixConstant.APP_NEW_LABEL_KEY, key);
            if (StringUtil.isEmpty(value)) {
                paasRedisHelper.setValue(RedisPrefixConstant.APP_NEW_LABEL_KEY, key, 1, RedisConstant.HUGE_DURATION);
            }
        }
        Boolean isStandardWithFeeType = packageHelp.isStandardWithFeeType(corpid);
        String alias = entity.getAlias();
        PaasAppEntity paasAppEntity;
        if (Objects.equals(CompanyConfigEnum.ELECTRONIC_FACE_SHEET.getAlias(), alias) || Objects.equals(CompanyConfigEnum.PRICE_MANAGE.getAlias(), alias) || Objects.equals(CompanyConfigEnum.LOGISTICS_TRACKING.getAlias(), alias)) {
            paasAppEntity = new PaasAppEntity();
            CompanyConfigEntity companyConfigEntity = companyConfigModel.getByConfigAlias(alias, corpid);
            paasAppEntity.setEnable((Objects.isNull(companyConfigEntity) || Objects.equals(companyConfigEntity.getConfigValue(), "0")) ? 0 : 1);
        } else {
            paasAppEntity = paasAppModel.getByAlias(entity.getAlias(), corpid);
        }
        if (Objects.equals(entity.getAlias(), ValueAddedTypeEnum.DISTRIBUTOR.getAlias())) {
            entity.setOperateType(AppOperateProcessEnum.APPLY_OPEN_INDEX.getOperateType());
        }
        BeanUtil.copyProperties(entity, detailVO);
        detailVO.setAppModuleId(entity.getId());
        AppModuleListDTO listDTO = new AppModuleListDTO();
        BeanUtil.copyProperties(detailDTO, listDTO);
        dealSpecialMarket(corpid, entity, paasAppEntity, isStandardWithFeeType ,listDTO);
        getOperateStatus(paasAppEntity, entity, detailVO, corpid, detailDTO.getPlatform());
        return detailVO;
    }

    /**
     * 获取该应用的可执行操作
     * @param paasAppEntity
     * @param appModuleEntity
     * @param appModulePojo
     * @param corpid
     * @param platform
     * @return void
     * @author 石安
     * @date 2020-01-02
     */
    private void getOperateStatus(PaasAppEntity paasAppEntity, AppModuleEntity appModuleEntity, AppModulePojo appModulePojo, String corpid, String platform){
        AppOperateProcessEnum processEnum = AppOperateProcessEnum.getByOperateType(appModuleEntity.getOperateType());
        appModulePojo.setIsOpenPurchase(false);
        if (paasAppEntity != null) {
            appModulePojo.setAppId(paasAppEntity.getId());
            appModulePojo.setIsOpen(true);
            // 该应用已被开通
            switch (processEnum) {
                case APPLY_TRIAL_INDEX:
                    appModulePojo.setOperate("");
                    break;
                case APPLY_OPEN_INDEX:
                case START_INDEX:
                    if (paasAppEntity.getEnable() == 0) {
                        appModulePojo.setOperate(ModuleAppOperateEnum.START.getAlias());
                    } else if (paasAppEntity.getEnable() == 1) {
                        appModulePojo.setOperate(ModuleAppOperateEnum.CLOSE.getAlias());
                    }
                    break;
                case TRIAL_OPEN_UPGRADERENEWAL_INDEX:
                case TRIAL_OPEN_INDEX:
                    if (Objects.equals(appModuleEntity.getAlias(), ValueAddedTypeEnum.SEARCH_CUSTOMER.getAlias())) {
                        //兼容：两个不能同时使用
                        //精线索 搜客
                        FineClueCompanyEntity fineClueCompanyEntity = fineClueCompanyModel.getByCorpid(corpid, FineClueEnum.FINE_CLUE.getType());
                        if(Objects.nonNull(fineClueCompanyEntity)){
                            //如果工商查询是试用或者过期状态
                            if (fineClueCompanyEntity.getExtraExpiry() - fineClueCompanyEntity.getAddTime() <4 * RedisTimeConstant.LONG_DURATION){
                                appModulePojo.setOperate(ModuleAppOperateEnum.OPEN.getAlias());
                            }else {
                                appModulePojo.setAppId(paasAppEntity.getId());
                                if (paasAppEntity.getEnable() == 1) {
                                    appModulePojo.setOperate(ModuleAppOperateEnum.CLOSE.getAlias());
                                }else if (paasAppEntity.getEnable() == 0) {
                                    appModulePojo.setOperate(ModuleAppOperateEnum.START.getAlias());
                                }
                            }
                        }
                        //搜客 搜客
                        SearchCustomerCompanyEntity companyEntity = searchCustomerCompanyModel.getByCorpid(corpid, SoukeMealEnum.SOUKE.getType());
                        Long extraExpiry = 0L;
                        Long addTime = 0L;
                        if (Objects.nonNull(companyEntity)) {
                            extraExpiry = companyEntity.getExtraExpiry();
                            addTime = companyEntity.getAddTime() == null ? 0L : companyEntity.getAddTime();
                        }else {
                            break;
                        }
                        if (extraExpiry - addTime < 4 * RedisTimeConstant.LONG_DURATION) {
                            appModulePojo.setOperate(ModuleAppOperateEnum.OPEN.getAlias());
                            appModulePojo.setIsOpen(false);
                        }else {
                            appModulePojo.setAppId(paasAppEntity.getId());
                            if (paasAppEntity.getEnable() == 1) {
                                appModulePojo.setOperate(ModuleAppOperateEnum.CLOSE.getAlias());
                            }else if (paasAppEntity.getEnable() == 0) {
                                appModulePojo.setOperate(ModuleAppOperateEnum.START.getAlias());
                            }
                        }
                    }
                     /*// 查看该套餐为试用还是正常套餐
                    PackageTypeEnum packageTypeEnum = PackageTypeEnum.getByAlias(appModuleEntity.getAlias());
                    List<FeeCompanyEntity> feeCompanyEntityList = feeCompanyModel.getByType(paasAppEntity.getCorpid(), packageTypeEnum.getType());
                    if (CollectionsUtil.isNotEmpty(feeCompanyEntityList)) {
                        if (feeCompanyEntityList.size() == 1 && feeCompanyEntityList.get(0).getRealPrice() == 0) {
                            // 只开通了免费试用套餐
                            appModulePojo.setOperate(ModuleAppOperateEnum.OPEN.getAlias());
                        } else {
                            // 开通了其他套餐
                            // appModulePojo.setOperate(ModuleAppOperateEnum.UPGRADERENEWAL.getAlias());
                        }
                    }*/
                    break;
                case INSTALL:
                    if (Objects.equals(PlatFormEnum.DINGTALK.getValue(), platform)) {
                        appModulePojo.setOperate("");
                    }else if (Objects.equals(PlatFormEnum.WEB.getValue(), platform)){
                        if(appModuleEntity.getMirrorId() != null){
                            List<Long> mirrorIdIn = appModuleEntity.getMirrorId().toJavaList(Long.class);
                            if(Objects.equals(mirrorIdIn.size(), 1)){
                                mirrorOperate(appModuleEntity, appModulePojo, corpid);
                            } else {
                                mirrorOperateAll(appModuleEntity, appModulePojo, corpid);
                            }
                        }
                    }
                    break;
                case AUTHORIZE:
                    if (paasAppEntity.getEnable() == 0) {
                        appModulePojo.setOperate(ModuleAppOperateEnum.OPEN_AUTHORIZATION.getAlias());
                    } else if (paasAppEntity.getEnable() == 1) {
                        appModulePojo.setOperate(ModuleAppOperateEnum.CLOSE_AUTHORIZATION.getAlias());
                    }
                    break;
                case OUTSIDE:
                    if (paasAppEntity.getEnable() == 0) {
                        appModulePojo.setOperate(ModuleAppOperateEnum.START.getAlias());
                    } else if (paasAppEntity.getEnable() == 1) {
                        appModulePojo.setOperate(ModuleAppOperateEnum.CLOSE.getAlias());
                    }
                    break;
                default:
                    appModulePojo.setOperate("");
                    break;
            }
        }else {
            appModulePojo.setIsOpen(false);
            // 应用未开通
            switch (processEnum) {
                case APPLY_TRIAL_INDEX:
                    appModulePojo.setOperate(ModuleAppOperateEnum.APPLYTRIAL.getAlias());
                    break;
                case APPLY_OPEN_INDEX:
                    appModulePojo.setOperate(ModuleAppOperateEnum.APPLYOPEN.getAlias());
                    break;
                case TRIAL_OPEN_UPGRADERENEWAL_INDEX:
                case TRIAL_OPEN_INDEX:
                    appModulePojo.setOperate(ModuleAppOperateEnum.TRIAL.getAlias());
                    if (Objects.equals(appModuleEntity.getAlias(), ValueAddedTypeEnum.BUSINESS_SEARCH.getAlias())) {
                        //精线索 工商查询  兼容：先查精线索表，如果精线索表查不到再查搜客表（两个不能同时使用）
                        FineClueCompanyEntity fineClueCompanyEntity = fineClueCompanyModel.getByCorpid(corpid, FineClueEnum.BUSINESS.getType());
                        if(Objects.nonNull(fineClueCompanyEntity)){
                            if (fineClueCompanyEntity.getExtraExpiry() - fineClueCompanyEntity.getAddTime() <4 * RedisTimeConstant.LONG_DURATION){
                                appModulePojo.setOperate(ModuleAppOperateEnum.OPEN.getAlias());
                            }else{
                                CompanyConfigEntity configEntity = companyConfigModel.getByConfigAlias(CompanyConfigEnum.BUSINESS_SEARCH.getAlias(), corpid);
                                String operate = Objects.nonNull(configEntity) ? (Objects.equals(configEntity.getConfigValue(), BasicConstant.ONE_STRING) ? ModuleAppOperateEnum.CLOSE.getAlias() : ModuleAppOperateEnum.START.getAlias()) : ModuleAppOperateEnum.START.getAlias();
                                appModulePojo.setOperate(operate);
                            }
                        } else {
                            //搜客 工商查询
                            SearchCustomerCompanyEntity companyEntity = searchCustomerCompanyModel.getByCorpid(corpid, SoukeMealEnum.BUSINESS.getType());
                            if (Objects.isNull(companyEntity)) {
                                break;
                            } else if (companyEntity.getExtraExpiry() - companyEntity.getAddTime() < 4 * RedisTimeConstant.LONG_DURATION) {
                                appModulePojo.setOperate(ModuleAppOperateEnum.OPEN.getAlias());
                            } else {
                                appModulePojo.setOperate("");
                            }
                        }
                    }
                    break;
                case START_INDEX:
                    appModulePojo.setOperate(ModuleAppOperateEnum.START.getAlias());
                    break;
                case INSTALL:
                case ONLY_NSTALL:
                    if (Objects.equals(PlatFormEnum.DINGTALK.getValue(), platform)) {
                        appModulePojo.setOperate("");
                    }else if (Objects.equals(PlatFormEnum.WEB.getValue(), platform)){
                        if(appModuleEntity.getMirrorId() != null){
                            List<Long> mirrorIdIn = appModuleEntity.getMirrorId().toJavaList(Long.class);
                            if(Objects.equals(mirrorIdIn.size(), 1)){
                                mirrorOperate(appModuleEntity, appModulePojo, corpid);
                            } else {
                                mirrorOperateAll(appModuleEntity, appModulePojo, corpid);
                            }
                        }
                    }
                    break;
                case AUTHORIZE:
                    appModulePojo.setOperate(ModuleAppOperateEnum.OPEN_AUTHORIZATION.getAlias());
                    break;
                case OUTSIDE:
                    appModulePojo.setOperate(ModuleAppOperateEnum.OPEN_OUTSIDE.getAlias());
                    break;
                default:
                    appModulePojo.setOperate("");
                    break;
            }
        }
        // 开启模版中心直接购买特殊处理
        if(DingTalkPayConstant.TEMPLATE_CENTER_OPENED_FOR_PURCHASE){
            appModulePojo.setIsOpenPurchase(true);
            String alias = appModuleEntity.getAlias();
            // 处理相应应用的goodsCode(服务包，工商查询，搜客，xbbcall，山海，云叩，增值服务)
            if(Objects.equals(alias, "fuwu") || Objects.equals(alias, ValueAddedTypeEnum.BUSINESS_SEARCH.getAlias()) || Objects.equals(alias, ValueAddedTypeEnum.SEARCH_CUSTOMER.getAlias()) ||
                    Objects.equals(alias, XbbRefTypeEnum.CALL_CENTER_XBB.getAlias()) || Objects.equals(alias, "shanhai") ||
                    Objects.equals(alias, ValueAddedTypeEnum.CLOUD.getAlias()) || Objects.equals(alias, ValueAddedTypeEnum.INCREMENT.getAlias())){
                String operate = appModulePojo.getOperate();
                if(Objects.equals(operate, ModuleAppOperateEnum.OPEN.getAlias()) || Objects.equals(operate, ModuleAppOperateEnum.APPLYOPEN.getAlias())){
                    appModulePojo.setOperate(ModuleAppOperateEnum.OPEN.getAlias());
                }
                Integer type = null;
                switch (alias) {
                    case "fuwu":
                        type = PackageTypeEnum.SERVICE.getType();
                        break;
                    case "businessSearch":
                        type = PackageTypeEnum.BUSINESS_SEARCH.getType();
                        break;
                    case "searchCustomer":
                        type = PackageTypeEnum.SEARCH_CUSTOMER.getType();
                        break;
                    case "xbb":
                        type = PackageTypeEnum.XBB_CALL.getType();
                        break;
                    case "dataKanban":
                        type = PackageTypeEnum.DATA_KANBAN.getType();
                    case "cloud":
                        type = PackageTypeEnum.CLOUD.getType();
                        break;
                    case "increment":
                        type = PackageTypeEnum.INCREMENT.getType();
                        break;
                    default:
                        break;
                }
                if(type != null){
                    Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    params.put("del", DelEnum.NORMAL.getDel());
                    // 内购套餐
                    params.put("type", type);
                    params.put("start", BasicConstant.ZERO);
                    params.put("pageNum", BasicConstant.ONE);
                    List<FeeEntity> feeEntityList = feeModel.findEntitys(params);
                    if(CollectionUtils.isEmpty(feeEntityList)){
                        return;
                    }
                    FeeEntity feeEntity = feeEntityList.get(0);
                    String goodsCode = feeEntity.getXinxuanProductCode();
                    appModulePojo.setGoodsCode(goodsCode);
                }
            }
        }
    }

    /**
     * 镜像应用是否安装
     * @param appModuleEntity
     * @param corpid
     * @return void
     * @author 石安
     * @date 2020-02-20
     */
    private void mirrorOperate(AppModuleEntity appModuleEntity, AppModulePojo appModulePojo, String corpid)  {
        JSONArray mirrorIdArr = appModuleEntity.getMirrorId();
        Long mirrorId = BasicConstant.ZERO_LONG;
        if(mirrorIdArr != null){
            mirrorId = mirrorIdArr.getLong(0);
        }
        MirrorInstructionDTO mirrorInstructionDTO = new MirrorInstructionDTO();
        mirrorInstructionDTO.setMirrorId(mirrorId);
        mirrorInstructionDTO.setCorpid(corpid);
        Locale locale = LocaleContextHolder.getLocale();
        String lang = locale.toString();
        XbbResponse<MirrorInstructionVO> response = mirrorFeignClent.getMirrorInstruction(mirrorInstructionDTO, lang);
        MirrorInstructionVO instructionVO = response.getResult();
        if (Objects.equals(instructionVO.getIsInstall(), 2)) {
            appModulePojo.setOperate("");
        } else if (Objects.equals(instructionVO.getIsInstall(), 0)) {
            appModulePojo.setOperate(ModuleAppOperateEnum.INSTALL.getAlias());
        } else if (Objects.equals(instructionVO.getIsInstall(), 1)) {
            if (Objects.equals(appModuleEntity.getOperateType(), AppOperateProcessEnum.ONLY_NSTALL.getOperateType())) {
                appModulePojo.setOperate("");
            } else {
                if (Objects.equals(instructionVO.getEnable(), 1)) {
                    appModulePojo.setAppId(instructionVO.getAppId());
                    appModulePojo.setOperate(ModuleAppOperateEnum.CLOSE.getAlias());
                } else if (Objects.equals(instructionVO.getEnable(), 0)) {
                    appModulePojo.setAppId(instructionVO.getAppId());
                    appModulePojo.setOperate(ModuleAppOperateEnum.START.getAlias());
                }
            }
        }
    }

    /**
     * 组合镜像应用是否安装
     * @param appModuleEntity
     * @param corpid
     * @return void
     * @author 石安
     * @date 2020-02-20
     */
    private void mirrorOperateAll(AppModuleEntity appModuleEntity, AppModulePojo appModulePojo, String corpid)  {
        Locale locale = LocaleContextHolder.getLocale();
        String lang = locale.toString();

        MirrorInstructionAllDTO mirrorInstructionAllDTO = new MirrorInstructionAllDTO();
        mirrorInstructionAllDTO.setAppModuleId(appModuleEntity.getId());
        mirrorInstructionAllDTO.setCorpid(corpid);
        XbbResponse<MirrorInstructionAllVO> response = mirrorFeignClent.getMirrorInstructionAll(mirrorInstructionAllDTO, lang);

        MirrorInstructionAllVO instructionVO = response.getResult();
        if (Objects.equals(instructionVO.getIsInstall(), 2) || Objects.equals(instructionVO.getIsInstall(), 1)) {
            appModulePojo.setOperate("");
        } else if (Objects.equals(instructionVO.getIsInstall(), 0)) {
            appModulePojo.setOperate(ModuleAppOperateEnum.INSTALL.getAlias());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AppModuleOpenVO open(AppModuleOpenDTO openDTO) throws XbbException {
        AppModuleOpenVO openVO = new AppModuleOpenVO();
        String corpid = openDTO.getCorpid();
        String alias = openDTO.getAlias();
        JSONArray mirrorIdArr = openDTO.getMirrorIdArr();
        String name = openDTO.getName();
        String icon = openDTO.getIcon();
        String color = openDTO.getBgColor();
        MenuInitVO menuInitVO = null;

        if (Objects.nonNull(openDTO.getAppModuleId())) {
            AppModuleEntity entity = appModuleModel.getByKey(openDTO.getAppModuleId());
            if (Objects.isNull(entity)) {
                throw new XbbException(TemplateCenterErrorCodeEnum.API_ERROR_402005, TemplateCenterErrorCodeEnum.API_ERROR_402005.getMsg());
            }
            if (Objects.equals(entity.getShelves(), 0)) {
                throw new XbbException(TemplateCenterErrorCodeEnum.API_ERROR_402006, TemplateCenterErrorCodeEnum.API_ERROR_402006.getMsg());
            }
            alias = entity.getAlias();
            mirrorIdArr = entity.getMirrorId();
            name = entity.getName();
            icon = entity.getIcon();
            color = entity.getBgColor();
            openDTO.setAlias(alias);
            openDTO.setMirrorIdArr(mirrorIdArr);
            openDTO.setName(name);
            openDTO.setIcon(icon);
            openDTO.setBgColor(color);
        }
        // 酷应用只有钉钉平台有
        if (Objects.equals(alias, XbbRefTypeEnum.COOL_APP.getAlias()) && !corpid.startsWith("ding")){
            throw new XbbException(CoolAppErrorCodeEnum.API_ERROR_1520010);
        }

        // 经销商申请试用
        if (Objects.equals(alias, ValueAddedTypeEnum.DISTRIBUTOR.getAlias())) {
            // 初始化经销商需要有进销存
            PaasAppEntity paasAppEntity = paasAppModel.getByAlias(XbbRefTypeEnum.JXC.getAlias(), corpid);
            if (Objects.isNull(paasAppEntity)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, "请先开通进销存");
            }
            if (packageHelp.isStandardWithFeeType(corpid)) {
                throw new XbbException(TemplateCenterErrorCodeEnum.API_ERROR_402008);
            }
            Long now = DateTimeUtil.getTodayInt();
            Long endTime = now + TimeConstant.SECONDS_PER_DAY * 30;
            List<FeeEntity> feeEntities = feeModel.getByType(ValueAddedTypeEnum.DISTRIBUTOR.getType());
            FeeEntity feeEntity = feeEntities.get(0);
            // fix:操作其他增值业务时插入了一条buy_num=0的经销商fee_log记录，导致之后在模版中心开通经销商时校验为已经试用过了
            boolean hasApplyTrial;
            List<FeeLogEntity> feeLogList = feeLogModel.getByType(openDTO.getCorpid(), ValueAddedTypeEnum.DISTRIBUTOR.getType());
            if (CollectionsUtil.isEmpty(feeLogList)) {
                // 没有feeLog记录表示没有开通过试用
                hasApplyTrial = false;
            } else {
                FeeLogEntity feeLogEntity = feeLogList.get(0);
                if (Objects.equals(feeLogEntity.getBuyNum(), 0)) {
                    feeLogModel.deleteByKey(feeLogEntity.getId(), feeLogEntity.getCorpid());
                    // 有一条buy_num=0的经销商fee_log记录也表示没有开通过试用
                    hasApplyTrial = false;
                } else {
                    // 有一条buy_num!=0的经销商fee_log记录表示已经开通过试用
                    hasApplyTrial = true;
                }
            }
            if (hasApplyTrial) {
                // 已经试用过则提示用户不能多次试用
                throw new XbbException(TemplateCenterErrorCodeEnum.API_ERROR_402009);
            }
            CompanyEntity companyEntity = companyModel.getByKey(openDTO.getCorpid());
            if (Objects.isNull(companyEntity)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100011);
            }

            FeeLogEntity mainFee = new FeeLogEntity();
            mainFee.setParentId(0L);
            mainFee.setCorpid(openDTO.getCorpid());
            mainFee.setCorpName(companyEntity.getCorpName());
            mainFee.setFeeType(0);
            mainFee.setFeeId(0L);
            mainFee.setFeeName("经销商免费试用");
            mainFee.setSumValue(0);
            mainFee.setRealPrice(0F);
            mainFee.setBuyNum(1);
            mainFee.setStartTime(now);
            mainFee.setEndTime(endTime);
            mainFee.setContent("经销商免费试用");
            mainFee.setFee(0F);
            mainFee.setIsPay(0);
            mainFee.setIsInvoice(0);
            mainFee.setPayType(1);
            mainFee.setOpUserName("超级管理员");
            mainFee.setOrderId("");
            mainFee.setMemo("");
            mainFee.setPayTime(now);
            mainFee.setAddTime(now);
            mainFee.setUpdateTime(now);
            mainFee.setDel(0);
            feeLogModel.insert(mainFee);

            FeeLogEntity feeLog = new FeeLogEntity();
            feeLog.setParentId(mainFee.getId());
            feeLog.setCorpid(openDTO.getCorpid());
            feeLog.setCorpName(companyEntity.getCorpName());
            feeLog.setFeeType(ValueAddedTypeEnum.DISTRIBUTOR.getType());
            feeLog.setFeeId(feeEntity.getId());
            feeLog.setFeeName(feeEntity.getName());
            feeLog.setSumValue(10);
            feeLog.setRealPrice(0F);
            feeLog.setBuyNum(1);
            feeLog.setStartTime(now);
            feeLog.setEndTime(endTime);
            feeLog.setContent("经销商免费试用");
            feeLog.setFee(0F);
            feeLog.setIsPay(0);
            feeLog.setIsInvoice(0);
            feeLog.setPayType(1);
            feeLog.setOpUserName("超级管理员");
            feeLog.setOrderId("");
            feeLog.setMemo("");
            feeLog.setPayTime(now);
            feeLog.setAddTime(now);
            feeLog.setUpdateTime(now);
            feeLog.setDel(0);
            feeLogModel.insert(feeLog);
            MenuInitDTO menuInitDTO = new MenuInitDTO();
            BeanUtil.copyProperties(openDTO, menuInitDTO);
            menuInitDTO.setAlias(alias);
            menuInitVO = initMenuHelp.menuInit(menuInitDTO);
        }

        PaasAppEntity paasAppEntity = null;
        // 获取已开通的应用模板
        if (Objects.nonNull(alias)) {
            paasAppEntity = paasAppModel.getByAlias(alias, corpid);
        } else {
            Long mirrorId = BasicConstant.ZERO_LONG;
            if(mirrorIdArr != null){
                mirrorId = mirrorIdArr.getLong(0);
            }
            // 判断应用是否已安装
            AppInstallEntity appInstallEntity = appInstallModel.getByMirrorId(mirrorId, corpid);
            if (Objects.nonNull(appInstallEntity)) {
                paasAppEntity = paasAppModel.getByKey(appInstallEntity.getAppId(), corpid);
            }
        }
        if (Objects.equals(openDTO.getOperate(), ModuleAppOperateEnum.START.getAlias())) {
            if (Objects.nonNull(paasAppEntity)) {
                openVO.setAppId(paasAppEntity.getId());
                paasAppEntity.setEnable(1);
                paasAppModel.update(paasAppEntity);
                //应用是市场管理的话，刷新缓存
                String marketManagementAlias = SystemAppMenuEnum.MARKET_MANAGEMENT.getAlias();
                if(Objects.equals(paasAppEntity.getAlias(),marketManagementAlias)){
                    paasAppService.setEnable2RedisByAlias(corpid,marketManagementAlias,paasAppEntity.getEnable());
                }
                if(Objects.equals(paasAppEntity.getAlias(), SystemAppMenuEnum.DISTRIBUTOR.getAlias())){
                    List<FeeLogEntity> feeLogEntities = feeLogModel.getByType(corpid, ValueAddedTypeEnum.DISTRIBUTOR.getType());
                    if (feeLogEntities.isEmpty() || feeLogEntities.get(feeLogEntities.size() - 1).getEndTime() < DateTimeUtil.getTodayInt()) {
                        throw new XbbException(TemplateCenterErrorCodeEnum.API_ERROR_402010);
                    }
                    initDistributorMenuHelp.enableDistributor(1, corpid, true);
                }
            } else if (Objects.nonNull(alias)) {
                List<String> enums = Arrays.asList(CompanyConfigEnum.ELECTRONIC_FACE_SHEET.getAlias(), CompanyConfigEnum.LOGISTICS_TRACKING.getAlias(), CompanyConfigEnum.PRICE_MANAGE.getAlias(),CompanyConfigEnum.BUSINESS_SEARCH.getAlias(),CompanyConfigEnum.TPLUS.getAlias());
                if (enums.contains(alias)) {
                    if (packageHelp.isStandardWithFeeType(corpid)
                            && !Objects.equals(CompanyConfigEnum.TPLUS.getAlias(), alias)) {
                        throw new XbbException(TemplateCenterErrorCodeEnum.API_ERROR_402008);
                    }
                    // 价格管理还需要增加或更新菜单
                    if (Objects.equals(alias, CompanyConfigEnum.PRICE_MANAGE.getAlias())) {
                        MenuInitDTO menuInitDTO = new MenuInitDTO();
                        BeanUtil.copyProperties(openDTO, menuInitDTO, true);
                        menuInitDTO.setAlias(XbbRefTypeEnum.DISTRIBUTOR.getAlias());
                        initPriceMenuHelp.initMenu(menuInitDTO, new HashMap<>());
                    } else if (Objects.equals(alias, CompanyConfigEnum.TPLUS.getAlias())) {
                        apiCallBackService.tplusApiCallbackSet(corpid, BasicConstant.IS_USE);
                    }
                    CompanyConfigEntity companyConfigEntity = companyConfigModel.getByConfigAlias(alias, corpid);
                    if (Objects.nonNull(companyConfigEntity)) {
                        companyConfigEntity.setConfigValue(BasicConstant.ONE.toString());
                        companyConfigModel.update(companyConfigEntity);
                    } else {
                        CompanyConfigEnum companyConfigEnum = CompanyConfigEnum.getByAlias(alias);
                        companyConfigEntity = new CompanyConfigEntity(corpid, companyConfigEnum.getName(), companyConfigEnum.getAlias(), BasicConstant.IS_USE.toString());
                        companyConfigModel.insert(companyConfigEntity);
                    }
                    openVO.setAppId(companyConfigEntity.getId());
                    return openVO;
                }
                MenuInitDTO initDTO = new MenuInitDTO();
                BeanUtil.copyProperties(openDTO, initDTO);
                initDTO.setAlias(alias);
                initDTO.setName(name);
                initDTO.setIcon(icon);
                initDTO.setColor(color);
                menuInitVO = initMenuHelp.menuInit(initDTO);



                // e签宝开通指定推送给王玲鲁
                LOG.info("模板中心：e签宝开通,指定推送给王玲鲁, alias = " + alias);
                if(Objects.equals(alias, "esign")){
                    LOG.info("模板中心：应用的第一次开启（开通应用）e签宝开通,新建销售机会消息推送");
                    try {
                        AppModuleSaveDTO saveDTO = new AppModuleSaveDTO();
                        BeanUtil.copyProperties(openDTO, saveDTO);

                        CompanyEntity companyEntity = companyModel.getByKey(corpid);
                        if(companyEntity == null) {
                            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100011);
                        }
                        String corpName = companyEntity.getCorpName();
                        saveDTO.setCompanyName(corpName);

                        // todo 因为E签宝越过网关，而且e签宝的回调里，都无法获取登陆信息loginvo，无法记录

                        addSalesOpportunity(saveDTO);
                    } catch (Exception e) {
                        LOG.error("e签宝开通,新建销售机会创建和消息推送", e);
                    }
                }
            }
        } else if (Objects.equals(openDTO.getOperate(), ModuleAppOperateEnum.CLOSE.getAlias())) {
            List<String> enums = Arrays.asList(CompanyConfigEnum.ELECTRONIC_FACE_SHEET.getAlias(), CompanyConfigEnum.LOGISTICS_TRACKING.getAlias(), CompanyConfigEnum.PRICE_MANAGE.getAlias(),CompanyConfigEnum.BUSINESS_SEARCH.getAlias(),CompanyConfigEnum.TPLUS.getAlias());
            if (enums.contains(alias)) {
                CompanyConfigEntity companyConfigEntity = companyConfigModel.getByConfigAlias(alias, corpid);
                if (Objects.nonNull(companyConfigEntity)) {
                    companyConfigEntity.setConfigValue(BasicConstant.ZERO.toString());
                    companyConfigModel.update(companyConfigEntity);
                } else {
                    CompanyConfigEnum companyConfigEnum = CompanyConfigEnum.getByAlias(alias);
                    companyConfigEntity = new CompanyConfigEntity(corpid, companyConfigEnum.getName(), companyConfigEnum.getAlias(), BasicConstant.ZERO.toString());
                    companyConfigModel.insert(companyConfigEntity);
                }
                // TODO 关闭价格管理菜单
                if (Objects.equals(alias, CompanyConfigEnum.PRICE_MANAGE.getAlias())) {
                    PaasMenuEntity paasMenuEntity = paasMenuModel.getByAlias4Distributor(XbbRefTypeEnum.PRICE_SET_PRODUCT.getAlias(), corpid, DistributorMarkEnum.DISTRIBUTOR.getCode());
                    if (Objects.nonNull(paasMenuEntity)) {
                        paasMenuEntity.setEnable(0);
                        paasMenuModel.update(paasMenuEntity);
                    }
                    priceSetModel.closePriceManage(corpid);
                } else if (Objects.equals(alias, CompanyConfigEnum.TPLUS.getAlias())) {
                    apiCallBackService.tplusApiCallbackSet(corpid, BasicConstant.NO_USE);
                }
                openVO.setAppId(companyConfigEntity.getId());
                return openVO;
            }
            if (Objects.isNull(paasAppEntity)) {
                throw new XbbException(TemplateCenterErrorCodeEnum.API_ERROR_402003, TemplateCenterErrorCodeEnum.API_ERROR_402003.getMsg());
            }else {
                openVO.setAppId(paasAppEntity.getId());
                paasAppEntity.setEnable(0);
                paasAppModel.update(paasAppEntity);
                //应用是市场管理的话，刷新缓存
                String marketManagementAlias = SystemAppMenuEnum.MARKET_MANAGEMENT.getAlias();
                if(Objects.equals(paasAppEntity.getAlias(),marketManagementAlias)){
                    paasAppService.setEnable2RedisByAlias(corpid,marketManagementAlias,paasAppEntity.getEnable());
                }
                if(Objects.equals(paasAppEntity.getAlias(), SystemAppMenuEnum.DISTRIBUTOR.getAlias())){
                    initDistributorMenuHelp.enableDistributor(0, corpid, false);
                }
            }
        }
        if (Objects.nonNull(menuInitVO)) {
            Map<String, PaasAppEntity> appMap = menuInitVO.getAppMap();
            if (Objects.nonNull(appMap) && appMap.containsKey(alias)) {
                PaasAppEntity paasAppEntityByMenu = appMap.get(alias);
                openVO.setAppId(paasAppEntityByMenu.getId());
            }
        }
        return openVO;
    }

    /**
     * 获取已开通的应用列表
     *
     * @param corpid 公司id
     * @param userId 用户id
     * @return
     * @throws
     * @author hongxiao
     * @date: 2019-03-04 11:04
     * @version v1.0
     * @since v1.0
     */
    @Override
    public Map<String, PaasAppEntity> getOpenApp(String corpid, String userId) throws XbbException {
        // 获取已开通的应用模板
        Map<String, PaasAppEntity> appEntityMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);

        // 应用类型
        List<Integer> saasMarkIn = new ArrayList<>();
        saasMarkIn.add(SaasMarkEnum.SAAS.getCode());
        saasMarkIn.add(SaasMarkEnum.THIRD_PARTY.getCode());

        EnableApplicationListDTO enableListDTO = new EnableApplicationListDTO();
        enableListDTO.setCorpid(corpid);
        enableListDTO.setUserId(userId);
        enableListDTO.setSaasMarkIn(saasMarkIn);
        // 不判断是否启用
        enableListDTO.setEnable(null);

        EnableApplicationListVO enableListVO = paasAppService.enableAppList(enableListDTO);
        if (enableListVO != null && CollectionsUtil.isNotEmpty(enableListVO.getAppList())) {
            List<PaasAppEntity> enableList = enableListVO.getAppList();
            enableList.forEach(item -> appEntityMap.put(item.getAlias(), item));
        }

        return appEntityMap;
    }

    @Override
    public AppModuleOpenVO appOpenDetail(@Valid AppModuleOpenDTO appModuleOpenDTO) throws XbbException {
        AppModuleOpenVO appModuleOpenVO = new AppModuleOpenVO();
        FeeLogEntityExt feeLogEntityExt = new FeeLogEntityExt();
        String corpid = appModuleOpenDTO.getCorpid();

        AppModuleEntity entity = appModuleModel.getByKey(appModuleOpenDTO.getAppModuleId());
        CompanyEntity companyEntity = companyModel.getByKey(corpid);
        if (Objects.isNull(entity)) {
            throw new XbbException(TemplateCenterErrorCodeEnum.API_ERROR_402005, TemplateCenterErrorCodeEnum.API_ERROR_402005.getMsg());
        }
        if (Objects.equals(entity.getShelves(), 0)) {
            throw new XbbException(TemplateCenterErrorCodeEnum.API_ERROR_402006, TemplateCenterErrorCodeEnum.API_ERROR_402006.getMsg());
        }
        AppModuleOpenVO.AppIcon appIcon = appModuleOpenVO.new AppIcon();
        appIcon.setIcon(entity.getIcon());
        appIcon.setBgColor(entity.getBgColor());

        PackageTypeEnum packageTypeEnum = PackageTypeEnum.getByAlias(appModuleOpenDTO.getAlias());
        List<FeeEntity> feeList = feeModel.getByType(packageTypeEnum.getType());
        Map<Long, FeeEntity> feeEntityMap = new HashMap<>(feeList.size());
        feeList.forEach(item -> feeEntityMap.put(item.getId(), item));
        List<FeeLogEntity> feeLogList = feeLogModel.getByType(corpid, packageTypeEnum.getType());
        // 以下逻辑是该应用已开通过的处理
        if (CollectionsUtil.isNotEmpty(feeLogList)) {
            //  获取当前开通的主套餐订单与增值套餐订单
            FeeLogEntity feeLogEntity = null;
            List<FeeLogEntity> feeAddLogEntitys = new ArrayList<>();
            for (FeeLogEntity feeLog : feeLogList) {
                if (feeEntityMap.get(feeLog.getFeeId()).getParentId() == 0) {
                    feeLogEntity = feeLog;
                } else {
                    feeAddLogEntitys.add(feeLog);
                }
            }

            if (feeLogEntity != null) {
                // 只展示当前开通的套餐及更高的套餐
                BeanUtil.copyProperties(feeLogEntity, feeLogEntityExt);
                feeLogEntityExt.setChildFeeCompanyList(feeAddLogEntitys);

                Long feeId = feeLogEntity.getFeeId();
                feeList.removeIf(feeEntity -> feeEntity.getId() < feeId);
            } else {
                feeList.removeIf(feeEntity -> feeEntity.getRealPrice() == 0f);
            }
        }

        Map<Long, FeeEntityExt> feeParentMap = new HashMap<>(feeList.size());
        feeList.forEach(item -> {
            if (item.getParentId() == 0L) {
                FeeEntityExt feeEntityExt = new FeeEntityExt();
                BeanUtil.copyProperties(item, feeEntityExt);
                if (item.getRealPrice() == 0) {
                    feeEntityExt.setName(I18nMessageUtil.getMessage(I18nStringConstant.FREE_TRIAL));
                } else {
                    feeEntityExt.setName(item.getContent());
                }
                feeParentMap.put(item.getId(), feeEntityExt);
            }
        });

        feeList.forEach(item -> {
            if (feeParentMap.keySet().contains(item.getParentId())) {
                List<FeeEntity> childList = new ArrayList<>();
                childList.add(item);
                feeParentMap.get(item.getParentId()).setChildList(childList);
            }
        });

        List<FeeEntityExt> feeEntityExts = feeParentMap.values().stream().sorted(Comparator.comparing(FeeEntity::getId)).collect(Collectors.toList());

        appModuleOpenVO.setName(entity.getName());
        appModuleOpenVO.setIcons(appIcon);
        appModuleOpenVO.setFeeImage(entity.getFeeImage());
        appModuleOpenVO.setOpenMealInfo(feeEntityExts);
        appModuleOpenVO.setEndTime(companyEntity.getFeeEndTime());
        appModuleOpenVO.setCurrentMeal(feeLogEntityExt);

        //试用状态返回
        String userId = appModuleOpenDTO.getUserId();
        String alias = appModuleOpenDTO.getAlias();
        Integer type = 0 ;
        if(Objects.equals(alias,"searchCustomer")){
            type = 1;
        }else if (Objects.equals(alias,"businessSearch")){
            type = 2;
        }

        FineClueCompanyEntity fineClueCompanyEntity = fineClueCompanyModel.getByCorpid(corpid, type);
        if (Objects.isNull(fineClueCompanyEntity)){
            //试用周期：在3天内可免费使用100条企业工商信息
            appModuleOpenVO.setTrialStatus(1);
            feeLogEntityExt.setEndTime(0L);
            appModuleOpenVO.setCurrentMeal(feeLogEntityExt);
        }else{
            //判断是否过期
            Long extraExpiry = fineClueCompanyEntity.getExtraExpiry();
            if (fineClueCompanyEntity != null && System.currentTimeMillis()/1000 < extraExpiry){
                feeLogEntityExt.setEndTime(extraExpiry);
                appModuleOpenVO.setCurrentMeal(feeLogEntityExt);
                // 2：  当前状态：试用中
                appModuleOpenVO.setTrialStatus(2);
            }
            if (fineClueCompanyEntity != null && System.currentTimeMillis()/1000 > extraExpiry){
                feeLogEntityExt.setEndTime(extraExpiry);
                appModuleOpenVO.setCurrentMeal(feeLogEntityExt);
                // 3：  已使用过试用权限，如需继续使用此功能，请开通正式版
                appModuleOpenVO.setTrialStatus(3);
            }
            feeLogEntityExt.setEndTime(fineClueCompanyEntity.getExtraExpiry());
            appModuleOpenVO.setCurrentMeal(feeLogEntityExt);
        }
        return appModuleOpenVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AppModuleSaveVO addMeal(@Valid AppModuleSaveDTO appModuleSaveDTO) throws XbbException {
        AppModuleSaveVO appModuleSaveVO = new AppModuleSaveVO();
        String operate = appModuleSaveDTO.getOperate();
        JSONObject jsonObject;
        PackageTypeEnum packageTypeEnum = PackageTypeEnum.getByAlias(appModuleSaveDTO.getAlias());
        FeeEntity feeEntity = feeModel.getByKey(appModuleSaveDTO.getFeeId());
        AppModuleEntity appModuleEntity = appModuleModel.getByAlias(appModuleSaveDTO.getAlias());
        if (Objects.isNull(appModuleEntity)) {
            throw new XbbException(TemplateCenterErrorCodeEnum.API_ERROR_402005, TemplateCenterErrorCodeEnum.API_ERROR_402005.getMsg());
        }
        if (Objects.equals(appModuleEntity.getShelves(), 0)) {
            throw new XbbException(TemplateCenterErrorCodeEnum.API_ERROR_402006, TemplateCenterErrorCodeEnum.API_ERROR_402006.getMsg());
        }

        try {
            switch (packageTypeEnum){
                case SEARCH_CUSTOMER:
                case BUSINESS_SEARCH:
                    jsonObject = registerApp(appModuleSaveDTO, feeEntity, packageTypeEnum);
                    if (Objects.equals(operate, ModuleAppOperateEnum.TRIAL.getAlias())) {
                        addSalesOpportunity(appModuleSaveDTO);
                    }

                    if (jsonObject.getInteger("error_code") != 0) {
                        appModuleSaveVO.setErrorCode(SearchCustomerErrorCodeEnum.API_ERROR_401017.getCode());
                        appModuleSaveVO.setMessage(SearchCustomerErrorCodeEnum.API_ERROR_401017.getMsg() + "：" + jsonObject.getString("message"));
                        appModuleSaveVO.setSuccess(false);
                        return appModuleSaveVO;
                    }

                    // TODO 支付宝支付或者银联支付
                    appModuleSaveVO = JSONObject.toJavaObject(jsonObject, AppModuleSaveVO.class);
                    if (Objects.equals(packageTypeEnum, PackageTypeEnum.SEARCH_CUSTOMER)) {
                        MenuInitDTO menuInitDTO = new MenuInitDTO();
                        BeanUtil.copyProperties(appModuleSaveDTO, menuInitDTO);
                        menuInitDTO.setAlias(packageTypeEnum.getAlias());
                        initMenuHelp.menuInit(menuInitDTO);

                        appModuleSaveVO.setReturnUrl(appModuleEntity.getRedirectUrl());
                    }
                    break;
                default:
                    break;
            }
        } catch (XbbException e) {
            LOG.info("试用开通失败--", e);
        }

        return appModuleSaveVO;
    }

    @Override
    public AppModuleSaveVO sendSMS(@Valid SendSMSDTO sendSMSDTO) throws XbbException {
        AppModuleSaveVO appModuleSaveVO = new AppModuleSaveVO();
        String mobile = sendSMSDTO.getMobile();
        // 产生验证码,6位数字
        String mobileCode = StringUtil.getRandomPassword(1, 6);

        String lastSend = paasRedisHelper.getValue(RedisPrefixConstant.REDIS_KEY_MOBILE_CODE_SEND, mobile);
        if (lastSend != null && UserConstant.REDIS_VALUE_MOBILE_CODE_SEND.equals(lastSend)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100009);
        }
        SmsSpacePojo smsCode = SMSSpaceService.sendCode(mobile, mobileCode);
        if (Objects.equals(smsCode.getSmsStatus(), "error")) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100010);
        }

        // 往redis添加数据
        paasRedisHelper.setValue(RedisPrefixConstant.REDIS_KEY_MOBILE_CODE, mobile, mobileCode, UserConstant.MOBILE_CODE_EFFECTIVE_TIME);
        paasRedisHelper.setValue(RedisPrefixConstant.REDIS_KEY_MOBILE_CODE_SEND, mobile, UserConstant.REDIS_VALUE_MOBILE_CODE_SEND,
                UserConstant.MOBILE_CODE_RESEND_DURATION);

        appModuleSaveVO.setErrorCode(0);
        appModuleSaveVO.setSuccess(true);
        appModuleSaveVO.setMessage("");
        appModuleSaveVO.setData((JSONObject) JSON.toJSON(smsCode));
        return appModuleSaveVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AppModuleSaveVO applyApp(AppModuleSaveDTO saveDTO) throws XbbException {
        if (Objects.equals(saveDTO.getAlias(), ValueAddedTypeEnum.DISTRIBUTOR.getAlias())) {
            Long now = DateTimeUtil.getTodayInt();
            Long endTime = now + TimeConstant.SECONDS_PER_DAY * 30;
            List<FeeEntity> feeEntities = feeModel.getByType(ValueAddedTypeEnum.DISTRIBUTOR.getType());
            FeeEntity feeEntity = feeEntities.get(0);
            boolean hasApplyTrial = feeLogModel.getByType(saveDTO.getCorpid(), ValueAddedTypeEnum.DISTRIBUTOR.getType()).isEmpty();
            if (!hasApplyTrial) {
                throw new XbbException(TemplateCenterErrorCodeEnum.API_ERROR_402009);
            }
            // TODO 查询是否有套餐记录，没有则生成30天套餐  生成主套餐 + 附属套餐
            FeeLogEntity mainFee = new FeeLogEntity();
            mainFee.setParentId(0L);
            mainFee.setCorpid(saveDTO.getCorpid());
            mainFee.setCorpName(saveDTO.getCompanyName());
            mainFee.setFeeType(0);
            mainFee.setFeeId(0L);
            mainFee.setFeeName("经销商免费试用");
            mainFee.setSumValue(0);
            mainFee.setRealPrice(0F);
            mainFee.setBuyNum(1);
            mainFee.setStartTime(now);
            mainFee.setEndTime(endTime);
            mainFee.setContent("经销商免费试用");
            mainFee.setFee(0F);
            mainFee.setIsPay(0);
            mainFee.setIsInvoice(0);
            mainFee.setPayType(1);
            mainFee.setOpUserName("超级管理员");
            mainFee.setOrderId("");
            mainFee.setMemo("");
            mainFee.setPayTime(now);
            mainFee.setAddTime(now);
            mainFee.setUpdateTime(now);
            mainFee.setDel(0);
            feeLogModel.insert(mainFee);

            FeeLogEntity feeLog = new FeeLogEntity();
            feeLog.setParentId(mainFee.getId());
            feeLog.setCorpid(saveDTO.getCorpid());
            feeLog.setCorpName(saveDTO.getCompanyName());
            feeLog.setFeeType(ValueAddedTypeEnum.DISTRIBUTOR.getType());
            feeLog.setFeeId(feeEntity.getId());
            feeLog.setFeeName(feeEntity.getName());
            feeLog.setSumValue(10);
            feeLog.setRealPrice(0F);
            feeLog.setBuyNum(1);
            feeLog.setStartTime(now);
            feeLog.setEndTime(endTime);
            feeLog.setContent("经销商免费试用");
            feeLog.setFee(0F);
            feeLog.setIsPay(0);
            feeLog.setIsInvoice(0);
            feeLog.setPayType(1);
            feeLog.setOpUserName("超级管理员");
            feeLog.setOrderId("");
            feeLog.setMemo("");
            feeLog.setPayTime(now);
            feeLog.setAddTime(now);
            feeLog.setUpdateTime(now);
            feeLog.setDel(0);
            feeLogModel.insert(feeLog);
            MenuInitDTO menuInitDTO = new MenuInitDTO();
            BeanUtil.copyProperties(saveDTO, menuInitDTO);
            menuInitDTO.setAlias(saveDTO.getAlias());
            initMenuHelp.menuInit(menuInitDTO);
        }
        return addSalesOpportunity(saveDTO);
    }

    /**
     * 新增一条销售机会
     * @param saveDTO
     * @return AppModuleSaveVO
     * @author 石安
     * @date 2020-01-13
     */
    @Override
    public AppModuleSaveVO addSalesOpportunity(AppModuleSaveDTO saveDTO) throws XbbException{
        AppModuleSaveVO appModuleSaveVO = new AppModuleSaveVO();
        appModuleSaveVO.setErrorCode(0);
        appModuleSaveVO.setSuccess(true);
        appModuleSaveVO.setMessage("");

        String xbbCorpId = getCorpId();
        String xbbUserId = getUserId();
        // 保存取出数据不为空，不加del条件
        UserEntity xbbUser = userModel.getByKeyIngoreDel(xbbUserId, xbbCorpId);
        LOG.info("-----------xbbCorpid =" + xbbCorpId + "-----xbbUserId=" + xbbUserId);
        if (StringUtil.isEmpty(xbbCorpId)) {
            return appModuleSaveVO;
        }
        UserVO userVO = new UserVO();
        BeanUtil.copyProperties(xbbUser, userVO);
        try {
            // 取到xbb的销售机会已启用模板，todo 需要固定机会表单
            // 骚操作
            PaasFormEntityExt paasFormEntityExt;
            if (Objects.equals(xbbCorpId, "dinge3fa697f86d461d2")) {
                paasFormEntityExt = paasFormModel.getByKey(572930L, xbbCorpId);
            } else {
                paasFormEntityExt = paasFormModel.getEnableFormList(xbbCorpId, XbbRefTypeEnum.SALES_OPPORTUNITY.getCode()).get(0);
            }
            PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByFormId(paasFormEntityExt.getId(), xbbCorpId);
            Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(paasFormExplainEntity.getExplains(), null);

            //查到该客户对应的xbb负责人与协同人
            CustomerCheckRepeatDTO repeatDTO = new CustomerCheckRepeatDTO();
            BeanUtil.copyProperties(saveDTO, repeatDTO);
            LOG.info("新建销售机会的公司" + saveDTO.getCompanyName());
            repeatDTO.setNameLike(saveDTO.getCompanyName());
            repeatDTO.setRule(CheckRepeatRuleEnum.NAME.getCode());
            repeatDTO.setCorpid(xbbCorpId);
            repeatDTO.setUserId(xbbUserId);
            XbbAggregatedPage<PaasFormDataEntityExt> customer = customerService.getDuplicateCustomer(repeatDTO);
            if (CollectionsUtil.isEmpty(customer.getContent())) {
                LOG.info("customer is empty");
                return appModuleSaveVO;
            }
            // 产品说名字会只存在一个，不允许客户名称重复
            PaasFormDataEntityExt paasFormDataEntityExt = customer.getContent().get(0);
            LOG.info("-----------------paasFormDataEntityExt = " + paasFormDataEntityExt);
            Long dataId = paasFormDataEntityExt.getDataId();
            DefaultOwnerAndCoUserGetDTO defaultOwnerAndCoUserGetDTO = new DefaultOwnerAndCoUserGetDTO();
            defaultOwnerAndCoUserGetDTO.setCorpid(xbbCorpId);
            defaultOwnerAndCoUserGetDTO.setBusinessType(XbbRefTypeEnum.SALES_OPPORTUNITY.getCode());
            defaultOwnerAndCoUserGetDTO.setSelectDataIdList(Collections.singletonList(dataId));
            defaultOwnerAndCoUserGetDTO.setSelectBusinessType(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode());
            DefaultOwnerAndCoUserGetVO ownerAndCoUser = paasFormDataService.getDefaultOwnerAndCoUser(defaultOwnerAndCoUserGetDTO);
            //新建销售机会
            OpportunityEntityExt opportunityEntityExt = setAvailableValue(paasFormEntityExt, ownerAndCoUser, paasFormDataEntityExt, explainMap, saveDTO, xbbUser);
            StageProcessEntity stageProcess = stageProcessModel.getEnableStageProcess(opportunityEntityExt.getCorpid(), opportunityEntityExt.getFormId());
            if (Objects.nonNull(stageProcess)) {
                SaleStageEntity stageStage = saleStageModel.getFirstStage(opportunityEntityExt.getCorpid(), opportunityEntityExt.getFormId(), stageProcess.getId());
                if (Objects.nonNull(stageStage)) {
                    boolean isNoWorkOrProportionEqualsZero = stageWorkModel.isNoWorkOrProportionEqualsZero(opportunityEntityExt.getCorpid(), opportunityEntityExt.getFormId(), stageProcess.getId(), stageStage.getId(), XbbRefTypeEnum.SALE_STAGE.getCode(), SaasMarkEnum.SAAS.getCode());
                    JSONObject dataList = opportunityEntityExt.getData();
                    dataList.put(SalesOpportunityEnum.SALE_STAGE.getAttr(), stageStage.getCode());
                    dataList.put(SalesOpportunityEnum.STAGE_PROCESS_ID.getAttr(), stageProcess.getId());
                    dataList.put(SalesOpportunityEnum.STAGE_ID.getAttr(), stageStage.getId());
                    dataList.put(SalesOpportunityEnum.STAGE_RATIO.getAttr(), isNoWorkOrProportionEqualsZero ? stageStage.getOutProportion() : stageStage.getIntoProportion());
                    LOG.info("-----------------新建销售机会实体 = " + opportunityEntityExt);
                    opportunityModel.insert(opportunityEntityExt);
                    // 保存销售机会阶段记录
                    OpportunityStageLogEntity saleStageLog = new OpportunityStageLogEntity();
                    saleStageLog.setCorpid(opportunityEntityExt.getCorpid());
                    saleStageLog.setFormId(opportunityEntityExt.getFormId());
                    saleStageLog.setDataId(opportunityEntityExt.getId());
                    saleStageLog.setStageCode(stageStage.getCode());
                    saleStageLog.setIsNow(1);
                    saleStageLog.setIntoTime(DateTimeUtil.getInt());
                    saleStageLog.setOutTime(0L);
                    saleStageLog.setAddTime(DateTimeUtil.getInt());
                    saleStageLog.setUpdateTime(DateTimeUtil.getInt());
                    saleStageLog.setDel(0);
                    saleStageLog.setStageProcessId(stageProcess.getId());
                    saleStageLog.setStageId(stageStage.getId());
                    saleStageLog.setStageType(stageStage.getType());
                    saleStageLog.setReasonId(BasicConstant.ONE);
                    saleStageLog.setMemo("");
                    saleStageLog.setHistoryStayTime(BasicConstant.ONE_LONG);
                    opportunityStageLogModel.save(saleStageLog);
                } else {
                    LOG.info("-----------------新建销售机会实体 = " + opportunityEntityExt);
                    opportunityModel.insert(opportunityEntityExt);
                }
            } else {
                LOG.info("-----------------新建销售机会实体 = " + opportunityEntityExt);
                opportunityModel.insert(opportunityEntityExt);
            }

            // e签宝开通指定推送给王玲鲁
            LOG.info("-----------------alias = " + saveDTO.getAlias());
            if(Objects.equals(saveDTO.getAlias(), "esign")){
                Long oppId = opportunityEntityExt.getDataId();
                String corpid = opportunityEntityExt.getCorpid();
                String creatorId = opportunityEntityExt.getCreatorId();
                // e签宝的极端情况处理，直接赋值负责人
                UpdateMyTeamDTO updateMyTeamDTO = new UpdateMyTeamDTO();
                updateMyTeamDTO.setBusinessType(XbbRefTypeEnum.SALES_OPPORTUNITY.getCode());
                updateMyTeamDTO.setSaasMark(BasicConstant.ONE);
                updateMyTeamDTO.setDataId(oppId);
                updateMyTeamDTO.setOwnerUserIds(Arrays.asList(xbbUser.getUserId()));
                updateMyTeamDTO.setCorpid(corpid);
                updateMyTeamDTO.setLoginUser(userVO);
                updateMyTeamDTO.setUserId(xbbUser.getUserId());
                updateMyTeamDTO.setPlatform(PlatFormEnum.WEB.getValue());
                saasDetailTabService.updateMyTeam(updateMyTeamDTO);
                try {
                    UserEntity creatorUser = userModel.getByKey(creatorId, corpid);
                    JSONObject data = opportunityEntityExt.getData();
                    String oppName = FastJsonHelper.getStringOrDefaultFromFormData(data, SalesOpportunityEnum.NAME.getAttr(), "");
                    String memo = oppName == "" ? opportunityEntityExt.getSerialNo() : String.format(I18nMessageUtil.getMessage(OpportunityPushConstant.OPPORTUNITY_TITLE), opportunityEntityExt.getSerialNo(), oppName);

                    // e签宝开通,新建销售机会消息推送
                    List<String> pushUserList = Arrays.asList(xbbUserId);
                    PushRefTypePojo.Options options = new PushRefTypePojo.Options(opportunityEntityExt.getAppId(), opportunityEntityExt.getMenuId(), opportunityEntityExt.getFormId(), oppId, Collections.singletonList(oppId), SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.SALES_OPPORTUNITY.getCode(), XbbRefTypeEnum.ALL_OPPORTUNITY.getCode());
                    MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, pushUserList, Collections.singletonList(oppId), 0, null, I18nMessageUtil.getMessage(OpportunityPushConstant.OPPORTUNITY_ADD_TITLE), String.format(I18nMessageUtil.getMessage(OpportunityPushConstant.OPPORTUNITY_ADD_CONTENT), creatorUser.getName(), memo), null, options);
                    baseProducer.sendMessage(PushTypeEnum.OPPORTUNITY_ADD_PUSH, messageRabbitMqDTO);
                } catch (Exception e) {
                    LOG.error("e签宝开通,新建销售机会消息推送", e);
                }
            }

            // 搜客试用/开通推送一条销售机会
            LOG.info("-----------------alias = " + saveDTO.getAlias());
            if(Objects.equals(saveDTO.getAlias(), "searchCustomer")){
                Long oppId = opportunityEntityExt.getDataId();
                String corpid = opportunityEntityExt.getCorpid();
                String creatorId = opportunityEntityExt.getCreatorId();
                Long id = opportunityEntityExt.getId();
                List<OpportunityUserEntity> opportunityUserEntityList = getOpportunityUserList(dataId, xbbCorpId, xbbUser);
                // 设置机会数据id
                opportunityUserEntityList.forEach(item -> item.setDataId(id));
                // 保存机会团队
                opportunityUserModel.insertBatch(opportunityUserEntityList,false);
                try {
                    UserEntity creatorUser = userModel.getByKey(creatorId, corpid);
                    JSONObject data = opportunityEntityExt.getData();
                    String oppName = FastJsonHelper.getStringOrDefaultFromFormData(data, SalesOpportunityEnum.NAME.getAttr(), "");
                    String memo = oppName == "" ? opportunityEntityExt.getSerialNo() : String.format(I18nMessageUtil.getMessage(OpportunityPushConstant.OPPORTUNITY_TITLE), opportunityEntityExt.getSerialNo(), oppName);

                    // 搜客试用/开通,新建销售机会消息推送
                    List<String> pushUserList = Arrays.asList(xbbUserId);
                    PushRefTypePojo.Options options = new PushRefTypePojo.Options(opportunityEntityExt.getAppId(), opportunityEntityExt.getMenuId(), opportunityEntityExt.getFormId(), oppId, Collections.singletonList(oppId), SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.SALES_OPPORTUNITY.getCode(), XbbRefTypeEnum.ALL_OPPORTUNITY.getCode());
                    MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, pushUserList, Collections.singletonList(oppId), 0, null, I18nMessageUtil.getMessage(OpportunityPushConstant.OPPORTUNITY_ADD_TITLE), String.format(I18nMessageUtil.getMessage(OpportunityPushConstant.OPPORTUNITY_ADD_CONTENT), creatorUser.getName(), memo), null, options);
                    baseProducer.sendMessage(PushTypeEnum.OPPORTUNITY_ADD_PUSH, messageRabbitMqDTO);
                } catch (Exception e) {
                    LOG.error("搜客试用/开通,新建销售机会消息推送", e);
                }
            }

            // 工商查询试用/开通推送一条销售机会
            LOG.info("-----------------alias = " + saveDTO.getAlias());
            if(Objects.equals(saveDTO.getAlias(), "businessSearch")){
                Long oppId = opportunityEntityExt.getDataId();
                String corpid = opportunityEntityExt.getCorpid();
                String creatorId = opportunityEntityExt.getCreatorId();
                Long id = opportunityEntityExt.getId();
                List<OpportunityUserEntity> opportunityUserEntityList = getOpportunityUserList(dataId, xbbCorpId, xbbUser);
                // 设置机会数据id
                opportunityUserEntityList.forEach(item -> item.setDataId(id));
                // 保存机会团队
                opportunityUserModel.insertBatch(opportunityUserEntityList,false);
                try {
                    UserEntity creatorUser = userModel.getByKey(creatorId, corpid);
                    JSONObject data = opportunityEntityExt.getData();
                    String oppName = FastJsonHelper.getStringOrDefaultFromFormData(data, SalesOpportunityEnum.NAME.getAttr(), "");
                    String memo = oppName == "" ? opportunityEntityExt.getSerialNo() : String.format(I18nMessageUtil.getMessage(OpportunityPushConstant.OPPORTUNITY_TITLE), opportunityEntityExt.getSerialNo(), oppName);

                    // 工商查询试用/开通,新建销售机会消息推送
                    List<String> pushUserList = Arrays.asList(xbbUserId);
                    PushRefTypePojo.Options options = new PushRefTypePojo.Options(opportunityEntityExt.getAppId(), opportunityEntityExt.getMenuId(), opportunityEntityExt.getFormId(), oppId, Collections.singletonList(oppId), SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.SALES_OPPORTUNITY.getCode(), XbbRefTypeEnum.ALL_OPPORTUNITY.getCode());
                    MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, pushUserList, Collections.singletonList(oppId), 0, null, I18nMessageUtil.getMessage(OpportunityPushConstant.OPPORTUNITY_ADD_TITLE), String.format(I18nMessageUtil.getMessage(OpportunityPushConstant.OPPORTUNITY_ADD_CONTENT), creatorUser.getName(), memo), null, options);
                    baseProducer.sendMessage(PushTypeEnum.OPPORTUNITY_ADD_PUSH, messageRabbitMqDTO);
                } catch (Exception e) {
                    LOG.error("工商查询试用/开通,新建销售机会消息推送", e);
                }
            }
            // 搜客增量包推送一条销售机会
            LOG.info("-----------------alias = " + saveDTO.getAlias());
            if(Objects.equals(saveDTO.getAlias(), ValueAddedTypeEnum.SEARCH_CUSTOMER_INC_PACKAGE.getAlias())){
                Long oppId = opportunityEntityExt.getDataId();
                String corpid = opportunityEntityExt.getCorpid();
                String creatorId = opportunityEntityExt.getCreatorId();
                Long id = opportunityEntityExt.getId();
                List<OpportunityUserEntity> opportunityUserEntityList = getOpportunityUserList(dataId, xbbCorpId, xbbUser);
                // 设置机会数据id
                opportunityUserEntityList.forEach(item -> item.setDataId(id));
                LOG.info("--------------opportunityUserEntityList:{}",JSON.toJSONString(opportunityUserEntityList));
                // 保存机会团队
                opportunityUserModel.insertBatch(opportunityUserEntityList,false);
                try {
                    UserEntity creatorUser = userModel.getByKey(creatorId, corpid);
                    JSONObject data = opportunityEntityExt.getData();
                    String oppName = FastJsonHelper.getStringOrDefaultFromFormData(data, SalesOpportunityEnum.NAME.getAttr(), "");
                    String memo = oppName == "" ? opportunityEntityExt.getSerialNo() : String.format(I18nMessageUtil.getMessage(OpportunityPushConstant.OPPORTUNITY_TITLE), opportunityEntityExt.getSerialNo(), oppName);

                    // 搜客增量包推送一条销售机会
                    List<String> pushUserList = Arrays.asList(xbbUserId);
                    PushRefTypePojo.Options options = new PushRefTypePojo.Options(opportunityEntityExt.getAppId(), opportunityEntityExt.getMenuId(), opportunityEntityExt.getFormId(), oppId, Collections.singletonList(oppId), SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.SALES_OPPORTUNITY.getCode(), XbbRefTypeEnum.ALL_OPPORTUNITY.getCode());
                    MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, pushUserList, Collections.singletonList(oppId), 0, null, I18nMessageUtil.getMessage(OpportunityPushConstant.OPPORTUNITY_ADD_TITLE), String.format(I18nMessageUtil.getMessage(OpportunityPushConstant.OPPORTUNITY_ADD_CONTENT), creatorUser.getName(), memo), null, options);
                    baseProducer.sendMessage(PushTypeEnum.OPPORTUNITY_ADD_PUSH, messageRabbitMqDTO);
                } catch (Exception e) {
                    LOG.error("搜客试用/开通,新建销售机会消息推送", e);
                }
            }

            // 公海池高级模式咨询推送一条销售机会
            LOG.info("-----------------alias = " + saveDTO.getAlias());
            if(Objects.equals(saveDTO.getAlias(), "publicPoolSeniorAsk")){
                Long oppId = opportunityEntityExt.getDataId();
                String corpid = opportunityEntityExt.getCorpid();
                String creatorId = opportunityEntityExt.getCreatorId();
                // 极端情况处理，直接赋值负责人
                UpdateMyTeamDTO updateMyTeamDTO = new UpdateMyTeamDTO();
                updateMyTeamDTO.setBusinessType(XbbRefTypeEnum.SALES_OPPORTUNITY.getCode());
                updateMyTeamDTO.setSaasMark(BasicConstant.ONE);
                updateMyTeamDTO.setDataId(oppId);
                if (Objects.nonNull(ownerAndCoUser) && CollectionsUtil.isNotEmpty(ownerAndCoUser.getOwnerList())) {
                    List ownerUserIds = new ArrayList();
                    List<ReturnUserAndDepartmentPojo> ownerList = ownerAndCoUser.getOwnerList();
                    ownerList.forEach(item ->{
                        String ownerId = Objects.toString(item.getId(), xbbUser.getUserId());
                        ownerUserIds.add(ownerId);
                    });
                    updateMyTeamDTO.setOwnerUserIds(ownerUserIds);
                } else {
                    updateMyTeamDTO.setOwnerUserIds(Arrays.asList(xbbUser.getUserId()));
                }
                updateMyTeamDTO.setCorpid(corpid);
                updateMyTeamDTO.setLoginUser(userVO);
                updateMyTeamDTO.setUserId(xbbUser.getUserId());
                updateMyTeamDTO.setPlatform(PlatFormEnum.WEB.getValue());
                saasDetailTabService.updateMyTeam(updateMyTeamDTO);
                try {
                    UserEntity creatorUser = userModel.getByKey(creatorId, corpid);
                    JSONObject data = opportunityEntityExt.getData();
                    String oppName = FastJsonHelper.getStringOrDefaultFromFormData(data, SalesOpportunityEnum.NAME.getAttr(), "");
                    String memo = oppName == "" ? opportunityEntityExt.getSerialNo() : String.format(I18nMessageUtil.getMessage(OpportunityPushConstant.OPPORTUNITY_TITLE), opportunityEntityExt.getSerialNo(), oppName);

                    // 公海池高级模式咨询生成销售机会消息推送
                    List<String> pushUserList = Arrays.asList(xbbUserId);
                    PushRefTypePojo.Options options = new PushRefTypePojo.Options(opportunityEntityExt.getAppId(), opportunityEntityExt.getMenuId(), opportunityEntityExt.getFormId(), oppId, Collections.singletonList(oppId), SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.SALES_OPPORTUNITY.getCode(), XbbRefTypeEnum.ALL_OPPORTUNITY.getCode());
                    MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, pushUserList, Collections.singletonList(oppId), 0, null, I18nMessageUtil.getMessage(OpportunityPushConstant.OPPORTUNITY_ADD_TITLE), String.format(I18nMessageUtil.getMessage(OpportunityPushConstant.OPPORTUNITY_ADD_CONTENT), creatorUser.getName(), memo), null, options);
                    baseProducer.sendMessage(PushTypeEnum.OPPORTUNITY_ADD_PUSH, messageRabbitMqDTO);
                } catch (Exception e) {
                    LOG.error("公海池高级模式咨询,新建销售机会消息推送", e);
                }
            }
            // 合同对比开通推送一条销售机会 contractCompareIncPackage 合同对比增量/试用推送一条销售机会
            LOG.info("-----------------alias = " + saveDTO.getAlias());
            if(Objects.equals(saveDTO.getAlias(), "contractCompare") || Objects.equals(saveDTO.getAlias(), "contractCompareIncPackage") || Objects.equals(saveDTO.getAlias(), "contractCompareTrial")){
                Long oppId = opportunityEntityExt.getDataId();
                String corpid = opportunityEntityExt.getCorpid();
                String creatorId = opportunityEntityExt.getCreatorId();
                Long id = opportunityEntityExt.getId();
                List<OpportunityUserEntity> opportunityUserEntityList = getOpportunityUserList(dataId, xbbCorpId, xbbUser);
                // 设置机会数据id
                opportunityUserEntityList.forEach(item -> item.setDataId(id));
                // 保存机会团队
                opportunityUserModel.insertBatch(opportunityUserEntityList,false);
                try {
                    UserEntity creatorUser = userModel.getByKey(creatorId, corpid);
                    JSONObject data = opportunityEntityExt.getData();
                    String oppName = FastJsonHelper.getStringOrDefaultFromFormData(data, SalesOpportunityEnum.NAME.getAttr(), "");
                    String memo = oppName == "" ? opportunityEntityExt.getSerialNo() : String.format(I18nMessageUtil.getMessage(OpportunityPushConstant.OPPORTUNITY_TITLE), opportunityEntityExt.getSerialNo(), oppName);

                    // 工商查询试用/开通,新建销售机会消息推送
                    List<String> pushUserList = Arrays.asList(xbbUserId);
                    PushRefTypePojo.Options options = new PushRefTypePojo.Options(opportunityEntityExt.getAppId(), opportunityEntityExt.getMenuId(), opportunityEntityExt.getFormId(), oppId, Collections.singletonList(oppId), SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.SALES_OPPORTUNITY.getCode(), XbbRefTypeEnum.ALL_OPPORTUNITY.getCode());
                    MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, pushUserList, Collections.singletonList(oppId), 0, null, I18nMessageUtil.getMessage(OpportunityPushConstant.OPPORTUNITY_ADD_TITLE), String.format(I18nMessageUtil.getMessage(OpportunityPushConstant.OPPORTUNITY_ADD_CONTENT), creatorUser.getName(), memo), null, options);
                    baseProducer.sendMessage(PushTypeEnum.OPPORTUNITY_ADD_PUSH, messageRabbitMqDTO);
                } catch (Exception e) {
                    LOG.error("合同对比开通,新建销售机会消息推送", e);
                }
            }
        }catch (Exception e){
            LOG.info("新建销售机会====", e);
        }
        return appModuleSaveVO;
    }

    /**
     * 获取机会团队列表
     * @param dataId
     * @param xbbCorpId
     * @return
     */
    private List<OpportunityUserEntity> getOpportunityUserList(Long dataId, String xbbCorpId, UserEntity xbbUser){
        // 机会团队
        List<UserTeamEntity> userTeamEntities = userTeamHelp.getUserTeamList(Arrays.asList(dataId), xbbCorpId, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), Boolean.FALSE, null);
        List<OpportunityUserEntity> opportunityUserEntityList = new ArrayList<>();
        if (CollectionsUtil.isEmpty(userTeamEntities)) {
            OpportunityUserEntity opportunityUserEntity = new OpportunityUserEntity();
            opportunityUserEntity.setCorpid(xbbCorpId);
            opportunityUserEntity.setUserId(xbbUser.getUserId());
            opportunityUserEntity.setUserName(xbbUser.getName());
            opportunityUserEntity.setUserAvatar(xbbUser.getAvatar());
            opportunityUserEntity.setCustomerId(dataId);
            opportunityUserEntity.setIsMain(BasicConstant.ONE);
            opportunityUserEntity.setDel(DelEnum.NORMAL.getDel());
            opportunityUserEntityList.add(opportunityUserEntity);
        }
        List<String> userIds = new ArrayList<>();
        userTeamEntities.forEach(item -> userIds.add(item.getUserId()));
        List<UserEntity> userEntityList = userModel.getByUserId(userIds, xbbCorpId);
        HashMap<String, String> avatarMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        userEntityList.forEach(item -> avatarMap.put(item.getUserId(), item.getAvatar()));
        for (UserTeamEntity userTeamEntity : userTeamEntities) {
            String avatar = avatarMap.getOrDefault(userTeamEntity.getUserId(),"");
            long now = DateTimeUtil.getInt();
            userTeamEntity.setAddTime(now);
            userTeamEntity.setUpdateTime(now);
            OpportunityUserEntity opportunityUserEntity = new OpportunityUserEntity();
            opportunityUserEntity.setCorpid(userTeamEntity.getCorpid());
            opportunityUserEntity.setUserId(userTeamEntity.getUserId());
            opportunityUserEntity.setUserName(userTeamEntity.getUserName());
            opportunityUserEntity.setUserAvatar(avatar);
            opportunityUserEntity.setCustomerId(dataId);
            opportunityUserEntity.setIsMain(userTeamEntity.getIsMain());
            opportunityUserEntity.setDel(DelEnum.NORMAL.getDel());
            opportunityUserEntityList.add(opportunityUserEntity);
        }
        return opportunityUserEntityList;
    }
    public static String getCorpId() {
        String projectName = ProBaseConfig.getProjectName();
        String corpid = "";
        //区分正式环境与测试环境
        if (projectName.startsWith("xbbProTest")) {
            // 测试lc5
            corpid = "ding0064986624e3b83b35c2f4657eb6378f";
        }else {
            corpid = ProBaseConfig.getXbbCorpId();
//            corpid = "xbb57e0490f68b7481d908397c9bd0cdc59";
        }
        return corpid;
    }

    public static String getUserId() {
        String projectName = ProBaseConfig.getProjectName();
        String userId = "";
        //区分正式环境与本地环境
        if (projectName.startsWith("xbbProTest")) {
            // 测试cl5
            userId = "385139392526159852";
        }else {
            userId = ProBaseConfig.getXbbUserId();
//            userId = "1637853246783";
        }
        return userId;
    }

    /**
     *
     * @param paasFormEntityExt 销售机会模板
     * @param ownerAndCoUser 负责人与协同人
     * @param paasFormDataEntityExt 客户
     * @param explainMap 销售机会模板的解释字段
     * @param saveDTO
     * @param xbbUser xbb用户
     * @return com.xbongbong.saas.domain.entity.ext.OpportunityEntityExt
     * @author 石安
     * @date 2020-04-20
     */
    private OpportunityEntityExt setAvailableValue(PaasFormEntityExt paasFormEntityExt, DefaultOwnerAndCoUserGetVO ownerAndCoUser, PaasFormDataEntityExt paasFormDataEntityExt,
                                                                        Map<String, FieldAttrEntity> explainMap, AppModuleSaveDTO saveDTO, UserEntity xbbUser) throws XbbException {
        String alias = saveDTO.getAlias();
        List<ReturnUserAndDepartmentPojo> ownerList = new ArrayList<>();
        OpportunityEntityExt opportunityEntityExt = new OpportunityEntityExt();
        opportunityEntityExt.setCorpid(xbbUser.getCorpid());
        opportunityEntityExt.setAppId(paasFormEntityExt.getAppId());
        opportunityEntityExt.setMenuId(paasFormEntityExt.getMenuId());
        opportunityEntityExt.setFormId(paasFormEntityExt.getId());
        opportunityEntityExt.setOwnerId(xbbUser.getUserId());
        opportunityEntityExt.setFlowStatus(FlowStatusEnum.NOT_NEED_APPROVAL.getType());
        opportunityEntityExt.setCreatorId(xbbUser.getUserId());
        opportunityEntityExt.setDepartmentId(0L);
        opportunityEntityExt.setDel(DelEnum.NORMAL.getDel());
        if (Objects.isNull(ownerAndCoUser) || CollectionsUtil.isEmpty(ownerAndCoUser.getOwnerList())) {
            ReturnUserAndDepartmentPojo pojo = new ReturnUserAndDepartmentPojo();
            BeanUtil.copyProperties(xbbUser, pojo);
            pojo.setId(xbbUser.getUserId());
            ownerList.add(pojo);
        } else {
            ownerList = ownerAndCoUser.getOwnerList();
        }

        if (CollectionsUtil.isNotEmpty(ownerList)) {
            opportunityEntityExt.setOwnerId(Objects.toString(ownerList.get(0).getId(), xbbUser.getUserId()));
        }

        // e签宝的极端情况处理，直接赋值负责人
        if(saveDTO.getLoginUser() == null){
            opportunityEntityExt.setOwnerId(xbbUser.getUserId());
        }

        for (FieldAttrEntity fieldAttrEntity : explainMap.values()) {
            // 获取流水号
            if (fieldAttrEntity.getFieldType() != null && fieldAttrEntity.getFieldType().equals(FieldTypeEnum.SERIALNO.getType())) {
                SerialNoDTO serialNoDTO = new SerialNoDTO();
                serialNoDTO.setCorpid(paasFormEntityExt.getCorpid());
                serialNoDTO.setFormId(paasFormEntityExt.getId());
                serialNoDTO.setSerialNumber(fieldAttrEntity.getSerialNumber());
                // 生成流水号
                SerialNoVO serialNoVO = serialNoHelp.getSerialNo(serialNoDTO);
                if (serialNoVO == null || StringUtils.isEmpty(serialNoVO.getSerialNo())) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.NO_SERIAL_NO);
                }
                opportunityEntityExt.setSerialNo(serialNoVO.getSerialNo());
            }
        }
        JSONObject dataList = new JSONObject();
        String name = saveDTO.getCompanyName();
        if(saveDTO.getLoginUserName() != null){
            name = name + "-" + saveDTO.getLoginUserName();
        }
        String linkName = saveDTO.getLoginUserName() == null ? name : saveDTO.getLoginUserName();

        float totalPrice = 0f;
        switch (alias) {
            case "professionalUsedUser":
                name += I18nMessageUtil.getMessage(I18nStringConstant.PROFESSIONAL_TRIAL);
                totalPrice = 100f;
                break;
            case "ultimate":
                name += I18nMessageUtil.getMessage(I18nStringConstant.ULTIMATE_TRIAL);
                totalPrice = 200f;
                break;
            case "searchCustomer":
                if (Objects.nonNull(saveDTO.getOperate()) && saveDTO.getOperate().equals("trial")){
                    name += I18nMessageUtil.getMessage(I18nStringConstant.SEARCHCUSTOMER_TRIAL);
                } else {
                    name += I18nMessageUtil.getMessage(I18nStringConstant.SEARCHCUSTOMER_OPEN);
                }
//                totalPrice = 2980f;
                break;
            case "searchCustomerIncPackage":
                name += ValueAddedTypeEnum.SEARCH_CUSTOMER_INC_PACKAGE.getName();
                break;
            case "businessSearch":
                if (Objects.nonNull(saveDTO.getOperate()) && saveDTO.getOperate().equals("trial")){
                    name += I18nMessageUtil.getMessage(I18nStringConstant.BUSINESSSEARCH_TRIAL);
                } else {
                    name += I18nMessageUtil.getMessage(I18nStringConstant.BUSINESSSEARCH_OPEN);
                }
//                totalPrice = 1000f;
                break;
            case "xbb":
            case "duyan":
                name += I18nMessageUtil.getMessage(I18nStringConstant.DUYAN_TRIAL);
                totalPrice = 120f;
                break;
            case "fuwu":
                name += I18nMessageUtil.getMessage(I18nStringConstant.FUWU_TRIAL);
                break;
            case "bundle":
                name += I18nMessageUtil.getMessage(I18nStringConstant.BUNDLE_TRIAL);
                break;
            case "esign":
                name += I18nMessageUtil.getMessage(I18nStringConstant.ESIGN_TRIAL);
                break;
            case "marketManagement":
                name += I18nMessageUtil.getMessage(I18nStringConstant.MARKET_MANAGEMENT_TRIAL);
                break;
            case "distributorManage":
                name += I18nMessageUtil.getMessage(I18nStringConstant.DISTRIBUTOR_TRIAL);
                break;
            case "publicPoolSeniorAsk":
                name += ValueAddedTypeEnum.PUBLIC_POOL_SENIOR_ASK.getName();
                break;
            case "contractCompare":
                name += I18nMessageUtil.getMessage(I18nStringConstant.CONTRACT_COMPARE);
                break;
            case "contractCompareIncPackage":
                name += I18nMessageUtil.getMessage(I18nStringConstant.CONTRACT_COMPARE_INCREASE);
                break;
            case "contractCompareTrial":
                name += I18nMessageUtil.getMessage(I18nStringConstant.CONTRACT_COMPARE_TRIAL);
                break;
            default:
                name += I18nMessageUtil.getMessage(I18nStringConstant.OPEN);
                break;
        }
        JSONObject data = paasFormDataEntityExt.getData();
        String customerName =(String) data.getOrDefault(CustomerManagementEnum.NAME.getAttr(), "");
        LOG.info("销售机会名称 = " + name);
        dataList.put(SalesOpportunityEnum.NAME.getAttr(), name);
        dataList.put(SalesOpportunityEnum.CUSTOMER_NAME.getAttr(), paasFormDataEntityExt.getId().toString());
        dataList.put(SalesOpportunityEnum.CUSTOMER_NAME_LINK_TEXT.getAttr(), customerName);
        dataList.put(SalesOpportunityEnum.ESTIMATE_AMOUNT.getAttr(), totalPrice);
        dataList.put(SalesOpportunityEnum.ESTIMATE_END_TIME.getAttr(), DateUtil.getInt() + RedisConstant.HUGE_DURATION);
        dataList.put(SalesOpportunityEnum.LAST_CONNECT_TIME.getAttr(), 0);
        dataList.put(SalesOpportunityEnum.COST.getAttr(), 0);
        dataList.put(SalesOpportunityEnum.GROSS_PROFIT.getAttr(), 0);
        dataList.put(SalesOpportunityEnum.COST.getAttr(), 0);
        dataList.put(SalesOpportunityEnum.GROSS_PROFIT_RATE.getAttr(), 0);
        dataList.put(SalesOpportunityEnum.EXCHANGE_RATE.getAttr(), 0);
        dataList.put(SalesOpportunityEnum.IMPORTANT_DEGREE.getAttr(), 0);
        dataList.put(SalesOpportunityEnum.IS_ARCHIVED.getAttr(), 2);
        dataList.put(SalesOpportunityEnum.PRODUCTS.getAttr(), new JSONArray());

        /*if (CollectionsUtil.isNotEmpty(ownerAndCoUser.getCoUserList())) {
            dataList.put(SalesOpportunityEnum.COUSER_ID.getAttr(), ownerAndCoUser.getCoUserList());
        }*/
        // e签宝的极端情况处理，直接赋值负责人（OWNER_ID不能放在data里面）
        /*if(saveDTO.getLoginUser() == null){
            dataList.put(SalesOpportunityEnum.OWNER_ID.getAttr(), Arrays.asList(xbbUser.getUserId()));
        }*/

       /* List<FieldAttrEntity> mobileFields = explainMap.values().stream().filter(item -> Objects.equals(item.getAttrName(), "联系电话")).collect(Collectors.toList());
        if (CollectionsUtil.isNotEmpty(mobileFields)) {
            FieldAttrEntity fieldAttrEntity = mobileFields.get(0);
            dataList.put(fieldAttrEntity.getAttr(), saveDTO.getMobile());
        }*/

        opportunityEntityExt.setData(dataList);
        return opportunityEntityExt;
    }

    @Override
    public AppRemindVO remindExpire(@Valid BaseDTO baseDTO) throws XbbException {
        AppRemindVO appRemindVO = new AppRemindVO();
        String corpid = baseDTO.getCorpid();
        String userId = baseDTO.getUserId();
        Set<AppRemindPojo> remindExpireList = new HashSet<>();
        UserVO user = baseDTO.getLoginUser();
        // 由于不同应用的订单信息存储在不同的表中，目前只能针对搜客，工商应用做判断是否到期
        List<SearchCustomerCompanyEntity> companyList = searchCustomerCompanyModel.getListByCorpid(corpid);
        if (CollectionsUtil.isNotEmpty(companyList)) {
            for (SearchCustomerCompanyEntity item : companyList) {
                AppModuleEntity entity = appModuleModel.getByAlias(SoukeMealEnum.getByType(item.getType()).getAlias());
                if (Objects.isNull(entity) || Objects.equals(entity.getShelves(), 0)) {
                    appRemindVO.setAdmin(user.isAdminOrBoss());
                    appRemindVO.setRemindExpireList(remindExpireList);
                    return appRemindVO;
                }

                AppRemindPojo remindPojo = new AppRemindPojo();
                BeanUtil.copyProperties(entity, remindPojo);
                remindPojo.setAppModuleId(entity.getId());
                remindPojo.setExpireTime(item.getExtraExpiry());
                if (item.getExtraExpiry() - DateUtil.getNow() < RedisConstant.LONG_DURATION && item.getExtraExpiry() > DateUtil.getNow() || item.getExtraExpiry() < DateUtil.getNow()) {
                    remindExpireList.add(remindPojo);
                }
            }
        }

        /**
         *  设计思路：普通员工的到期提醒存redis中一周，超管或老板的到期提醒存数据库中，
         *  普通员工与超管的即将到期提醒都存redis中一天
         */
        if (CollectionsUtil.isNotEmpty(remindExpireList)) {
            Iterator<AppRemindPojo> iterator = remindExpireList.iterator();
            while (iterator.hasNext()) {
                AppRemindPojo item = iterator.next();
                String value = "";
                if (item.getExpireTime() - DateUtil.getNow() < RedisConstant.LONG_DURATION && item.getExpireTime() > DateUtil.getNow()) {
                    // 即将到期的应用（到期时间距离现在不足一天）
                    value = paasRedisHelper.getValue(RedisPrefixConstant.APP_WILL_EXPIRE_REMIND, item.getAlias() + corpid + userId);
                    if (StringUtil.isEmpty(value)) {
                        paasRedisHelper.setValue(RedisPrefixConstant.APP_WILL_EXPIRE_REMIND, item.getAlias() + corpid + userId, 1, RedisConstant.LONG_DURATION);
                    } else {
                        iterator.remove();
                    }
                }else if (item.getExpireTime() < DateUtil.getNow()) {
                    if (user.isAdminOrBoss()) {
                        String alias = UserConfigEnum.APP_EXPIRE_REMIND.getAlias() + "_" + item.getAlias();
                        UserConfigEntity userConfigEntity = userConfigModel.getByUserId(userId, corpid, alias);
                        if (userConfigEntity != null && Objects.equals(userConfigEntity.getConfigValue(), "1")) {
                            iterator.remove();
                        } else if (userConfigEntity == null) {
                            UserConfigEntity userConfig = new UserConfigEntity();
                            BeanUtil.copyProperties(user, userConfig);
                            userConfig.setConfigAlias(alias);
                            userConfig.setConfigName(UserConfigEnum.APP_EXPIRE_REMIND.getName());
                            userConfig.setConfigValue("1");
                            userConfig.setDel(0);
                            userConfigModel.insert(userConfig);
                            // TODO 推送一条到期提醒给该用户

                        }
                    }else if (DateUtil.getNow() - item.getExpireTime() < RedisConstant.HUGE_DURATION) {
                        value = paasRedisHelper.getValue(RedisPrefixConstant.APP_EXPIRE_REMIND, item.getAlias() + corpid + userId);
                        if (StringUtil.isEmpty(value)) {
                            paasRedisHelper.setValue(RedisPrefixConstant.APP_EXPIRE_REMIND, item.getAlias() + corpid + userId, 1, RedisConstant.HUGE_DURATION);
                        } else {
                            iterator.remove();
                        }
                    }else {
                        iterator.remove();
                    }
                }
            }
        }
        appRemindVO.setAdmin(user.isAdminOrBoss());
        appRemindVO.setRemindExpireList(remindExpireList);
        return appRemindVO;
    }

    @Override
    public AppModuleHotVO hot(@Valid BaseDTO hotDTO) throws XbbException {
        AppModuleHotVO hotVO = new AppModuleHotVO();
        // todo 等模板中心改造完成再去掉注释
        // 获取列表
//        List<AppModuleEntity> list = appModuleModel.getAllList();
//        // 产品定的固定四个：销帮帮呼叫中心、 高级版、 搜客、 工商 （别问我为什么，问舒心）
//        List<AppModulePojo> resultList = new ArrayList<>();
//        list.forEach(entity ->{
//            List<String> aliasList = Arrays.asList("searchCustomer", "businessSearch");
//            if (aliasList.contains(entity.getAlias())) {
//                AppModulePojo pojo = new AppModulePojo();
//                BeanUtil.copyProperties(entity, pojo);
//                pojo.setAppModuleId(entity.getId());
//                resultList.add(pojo);
//            }
//        });
//
//        hotVO.setList(resultList);
        return hotVO;
    }

    @Override
    public AppModuleDisenableListVO disenableList(BaseDTO appModuleDisenableListDTO) throws XbbException {

        AppModuleDisenableListVO appModuleDisenableListVO = new AppModuleDisenableListVO();

        //判断是否有模版中心权限
        UserVO loginUser = appModuleDisenableListDTO.getLoginUser();
        Set<String> permSet = loginUser.getPermSet();
        if (permSet.contains(ProPermissionAliasEnum.MODULE_CENTER.getAlias())) {
            appModuleDisenableListVO.setHasPermission(true);
        } else {
            appModuleDisenableListVO.setHasPermission(false);
        }

        // 获取列表 筛选app_type不是模板
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("shelves", 1);
        param.put("appTypeNotIn", 3);
        param.put("del", DelEnum.NORMAL.getDel());
        List<AppModuleEntity> appList = appModuleModel.findEntitys(param);
        appList.forEach(item -> {
            // 展示“new”标签的处理
            if (appModuleHelp.showNewLabel(item, item.getId() + loginUser.getCorpid() + loginUser.getUserId())) {
                appModuleDisenableListVO.setIsNew(true);
            }
        });

        List<AppModuleEntity> list = appList.stream().filter(item -> !Objects.equals(item.getAppType(), 3))
                .sorted(Comparator.comparing(AppModuleEntity::getId)).collect(Collectors.toList());

        List<AppModulePojo> pojoList = new ArrayList<>();
        list.forEach(item -> {
            if (pojoList.size() >= 4) {
                return;
            }
            AppModulePojo appModulePojo = new AppModulePojo();
            BeanUtil.copyProperties(item, appModulePojo);
            appModulePojo.setAppModuleId(item.getId());
            pojoList.add(appModulePojo);
        });
        appModuleDisenableListVO.setAppList(pojoList);
        return appModuleDisenableListVO;
    }


    /**
     * 注册应用
     * @param appModuleSaveDTO 开通参数
     * @param feeEntity 套餐信息
     * @param packageTypeEnum 套餐枚举
     * @return JSONObject
     * @author 石安
     * @date 2020-01-08
     */
    private JSONObject registerApp(@Valid AppModuleSaveDTO appModuleSaveDTO, FeeEntity feeEntity, PackageTypeEnum packageTypeEnum) throws XbbException {
        JSONObject jsonObject = new JSONObject();
        String operate = appModuleSaveDTO.getOperate();
        switch (packageTypeEnum){
            case SEARCH_CUSTOMER:
            case BUSINESS_SEARCH:
                int type = 0;
                SearchCustomerDTO searchCustomerDTO = new SearchCustomerDTO();
                if (Objects.equals(operate, ModuleAppOperateEnum.TRIAL.getAlias())) {
                    searchCustomerDTO.setUid(appModuleSaveDTO.getCorpid() + packageTypeEnum.getType());
                } else {
                    searchCustomerDTO.setUid(appModuleSaveDTO.getCorpid() + appModuleSaveDTO.getUserId());
                }
                searchCustomerDTO.setExpiry_time(appModuleSaveDTO.getExtraExpiry() * 1000L);
                searchCustomerDTO.setCorpid(appModuleSaveDTO.getCorpid());
                searchCustomerDTO.setUserId(appModuleSaveDTO.getUserId());
                searchCustomerDTO.setCompany_name(appModuleSaveDTO.getCompanyName());
                searchCustomerDTO.setUsername(appModuleSaveDTO.getLoginUserName());
                searchCustomerDTO.setRole("mainaccount");
                // 套餐记录
                List<SearchCustomerMealDTO> meals = new ArrayList<>();
                SearchCustomerMealDTO mealDTO = new SearchCustomerMealDTO();
                if (Objects.equals(packageTypeEnum, PackageTypeEnum.SEARCH_CUSTOMER)) {
                    mealDTO.setType(feeEntity.getName());
                    type = SoukeMealEnum.SOUKE.getType();
                } else if (Objects.equals(packageTypeEnum, PackageTypeEnum.BUSINESS_SEARCH)) {
                    mealDTO.setType(I18nMessageUtil.getMessage(I18nStringConstant.ANONYMOUS_PACKAGE));
                    type = SoukeMealEnum.BUSINESS.getType();
                }
                meals.add(mealDTO);
                searchCustomerDTO.setMeals(meals);
                // 增值套餐记录
                Extra extra = new Extra();
                extra.setEnableTask(false);
                extra.setExtraSubCount(appModuleSaveDTO.getAddCount());
                searchCustomerDTO.setExtra(extra);
                LOG.info("搜客注册参数信息" + searchCustomerDTO.toString());
                jsonObject = searchCustomerService.sendRegister(searchCustomerDTO);
                if (Objects.isNull(jsonObject)) {
                    jsonObject = new JSONObject();
                }
                LOG.info("注册搜客" + jsonObject.toString());

                searchCustomerDTO.setExtraExpiry(PaasDateUtil.getDayLastSecond(appModuleSaveDTO.getExtraExpiry()));
                LOG.info("开始调用保存搜客套餐接口----searchCustomerDTO: " + searchCustomerDTO + "==========feeEntity:" + feeEntity +"=========type" + type + "=========operate" + operate);

                // 保存搜客套餐
                SearchCustomerCompanyEntity searchCustomerCompanyEntity = saveSoukeMeal(searchCustomerDTO, feeEntity, packageTypeEnum, type, operate);
                // 保存企业订单
                saveFeeOrder(appModuleSaveDTO, feeEntity, searchCustomerCompanyEntity.getExtraExpiry());
                break;
            default:
                break;
        }
        return jsonObject;
    }

    /**
     * 保存开通搜客的信息
     * @param searchCustomerDTO
     * @param feeEntity
     * @param packageTypeEnum
     * @param type
     * @param operate
     * @return void
     * @author 石安
     * @date 2019-12-30
     */
    private SearchCustomerCompanyEntity saveSoukeMeal(SearchCustomerDTO searchCustomerDTO, FeeEntity feeEntity, PackageTypeEnum packageTypeEnum, int type, String operate) throws XbbException {
        SearchCustomerCompanyEntity entity = searchCustomerCompanyModel.getByCorpid(searchCustomerDTO.getCorpid(), type);
        if (entity == null) {
            entity = new SearchCustomerCompanyEntity();
            entity.setType(type);
            entity.setCompanyName(searchCustomerDTO.getCompany_name());
        }
        BeanUtil.copyProperties(searchCustomerDTO, entity);

        if (Objects.equals(packageTypeEnum, PackageTypeEnum.SEARCH_CUSTOMER)) {
            entity.setNumType(SoukeNumTypeEnum.TRIAL_MEAL.getNum());
            JSONObject data = searchCustomerService.userPackage(searchCustomerDTO);
            LOG.info("（主/子）账号套餐数据信息=====" + data);
            if (data != null) {
                JSONObject dataObj = data.getJSONObject("data");
                JSONObject packageObj = dataObj.getJSONObject("package");
                JSONArray meals = packageObj.getJSONArray("meals");
                JSONObject meal = meals.getJSONObject(0);
                int mainAccounts = meal.getInteger("mainaccounts");
                int subAccounts = meal.getInteger("subaccounts");
                int extraSubCount = meal.getInteger("extraSubCount");
                entity.setUseCount(mainAccounts + subAccounts + extraSubCount);
                Long expiryTime = dataObj.getLong("expiry_time");
                entity.setExtraExpiry(expiryTime/1000);
            }
            data = searchCustomerService.info(searchCustomerDTO);
            String clueUserId = "";
            if (data != null) {
                JSONObject object = data.getJSONObject("data");
                clueUserId = object.getString("user_id");
            }
            if (!Objects.equals(operate, ModuleAppOperateEnum.TRIAL.getAlias())) {
                entity.setNumType(feeEntity.getPrimaryNum());
                SearchCustomerUserEntity searchCustomerUserEntity = searchCustomerUserModel.getByKey(searchCustomerDTO.getUserId(), searchCustomerDTO.getCorpid());
                if (searchCustomerUserEntity == null){
                    searchCustomerUserEntity = new SearchCustomerUserEntity();
                    // 设置开通人为主账户
                    BeanUtil.copyProperties(searchCustomerDTO, searchCustomerUserEntity);
                    searchCustomerUserEntity.setAdmin(1);
                    searchCustomerUserEntity.setStaff(1);
                    searchCustomerUserEntity.setIsBind(1);
                    searchCustomerUserEntity.setDel(DelEnum.NORMAL.getDel());
                }
                searchCustomerUserEntity.setClueUserId(clueUserId);
                searchCustomerUserModel.save(searchCustomerUserEntity);
            }
        } else if (Objects.equals(packageTypeEnum, PackageTypeEnum.BUSINESS_SEARCH)) {
            entity.setNumType(0);
            entity.setUseCount(0);
        }

        LOG.info("开始调用保saveSoukeMeal接口" + entity);
        searchCustomerCompanyModel.saveSoukeMeal(entity);
        return entity;
    }

    /**
     * 生成企业订单
     * @param appModuleSaveDTO
     * @param feeEntity
     * @return void
     * @author 石安
     * @date 2020-01-08
     */
    private void saveFeeOrder(@Valid AppModuleSaveDTO appModuleSaveDTO, FeeEntity feeEntity, Long extraExpiry) throws XbbException{
        FeeLogEntity feeLogEntity = new FeeLogEntity();
        feeLogEntity.setCorpid(appModuleSaveDTO.getCorpid());
        feeLogEntity.setCorpName(appModuleSaveDTO.getCompanyName());
        feeLogEntity.setFeeType(feeEntity.getType());
        feeLogEntity.setFeeId(feeEntity.getId());
        feeLogEntity.setFeeName(PackageTypeEnum.getByType(feeEntity.getType()).getName() + feeEntity.getName());
        feeLogEntity.setRealPrice(appModuleSaveDTO.getTotalPrice());
        feeLogEntity.setFee(feeEntity.getRealPrice());
        feeLogEntity.setSumValue(1);
        feeLogEntity.setIsPay(1);
        feeLogEntity.setPayType(2);
        feeLogEntity.setBuyNum(1);
        feeLogEntity.setOpUserName(appModuleSaveDTO.getLoginUserName());
        feeLogEntity.setPayTime(DateUtil.getNow());
        feeLogEntity.setStartTime(DateUtil.getNow());
        feeLogEntity.setEndTime(extraExpiry);
        feeLogEntity.setDel(DelEnum.NORMAL.getDel());
        feeLogModel.save(feeLogEntity);

        // 增值套餐订单的保存
        FeeEntity feeAddEntity = feeModel.getByKey(appModuleSaveDTO.getAddFeeId());
        if (feeAddEntity != null) {
            FeeLogEntity feeAddLog = new FeeLogEntity();
            feeAddLog.setCorpid(appModuleSaveDTO.getCorpid());
            feeAddLog.setCorpName(appModuleSaveDTO.getCompanyName());
            feeAddLog.setFeeType(feeAddEntity.getType());
            feeAddLog.setFeeId(feeAddEntity.getId());
            feeAddLog.setFeeName(PackageTypeEnum.getByType(feeAddEntity.getType()).getName() + feeAddEntity.getName());
            feeAddLog.setRealPrice(appModuleSaveDTO.getTotalPrice());
            feeAddLog.setFee(feeAddEntity.getRealPrice());
            feeAddLog.setIsPay(1);
            feeAddLog.setPayType(2);
            feeAddLog.setBuyNum(appModuleSaveDTO.getAddCount());
            feeAddLog.setSumValue(appModuleSaveDTO.getAddCount());
            feeAddLog.setOpUserName(appModuleSaveDTO.getLoginUserName());
            feeAddLog.setPayTime(DateUtil.getNow());
            feeAddLog.setStartTime(DateUtil.getNow());
            feeAddLog.setEndTime(extraExpiry);
            feeAddLog.setDel(DelEnum.NORMAL.getDel());
            feeLogModel.save(feeAddLog);
        }
    }

    @Override
    public EsignCorpStatusVO getEsignCorpStatus(BaseDTO baseDTO) throws XbbException {
        return esignHelp.getCorpStatus(baseDTO.getCorpid());
    }

    @Override
    public EsignAuthUrlVO getEsignAuthUrl(EsignAuthUrlDTO esignAuthUrlDTO) throws XbbException {
        EsignAuthUrlVO esignAuthUrlVO = esignHelp.getEsignAuthUrl(esignAuthUrlDTO);
        EsignTaskEntity esignTask = new EsignTaskEntity();
        esignTask.setCorpid(esignAuthUrlDTO.getCorpId());
        esignTask.setFormId(0L);
        esignTask.setDataId(0L);
        esignTask.setTaskId(esignAuthUrlVO.getTaskId());
        esignTask.setFileName("");
        esignTask.setType(EsignTaskTypeEnum.AUTHORIZE.getCode());
        esignTaskModel.insert(esignTask);
        return esignAuthUrlVO;
    }

    /**
     * 获取该配置的可执行操作
     * @param aliasValue
     * @param appModulePojo
     * @return void
     * @author lee
     * @date 2020-01-02
     */
    private void getOperateStatusByConfig(String aliasValue, AppModulePojo appModulePojo){
        if (StringUtil.isNotEmpty(aliasValue)) {
            appModulePojo.setIsOpen(true);
            if (Objects.equals(aliasValue, "1")) {
                appModulePojo.setOperate(ModuleAppOperateEnum.CLOSE.getAlias());
            } else {
                appModulePojo.setOperate(ModuleAppOperateEnum.START.getAlias());
            }
        }else {
            appModulePojo.setIsOpen(false);
            appModulePojo.setOperate(ModuleAppOperateEnum.START.getAlias());
        }
    }
}
